我可以等待不是当前Shell终端的子进程的进程终止吗? [英] Can i wait for a process termination that is not a child of current shell terminal?
问题描述
我有一个脚本,该脚本必须杀死由高可用性中间件管理的资源一定次数.它基本上检查资源是否正在运行,然后将其杀死,我需要proc被真正终止的时间戳.所以我做了这段代码:
#!/bin/bash
echo "$(date +"%T,%N") :New measures Run" > /home/hassan/logs/measures.log
for i in {1..50}
do
echo "Iteration: $i"
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
if [ -n "$PID" ]; then
echo "$(date +"%T,%N") :Killing $PID" >> /home/hassan/logs/measures.log
ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print "kill -9 " $2'} | sh
wait $PID
else
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
until [ -n "$PID" ]; do
sleep 2
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
done
fi
done
但是使用我的等待命令,我会收到以下错误消息:wait:pid xxxx不是此shell的子项
我假设您从 bash ,然后启动此脚本以等待.问题在于,子进程不是运行脚本,但运行其父级的子级!
如果您要在当前您应该以.
开头.
一个例子.启动vim
,然后停止按^Z
(以后可以使用fg
返回vim
).然后,您可以使用jobs
命令获取作业列表.
$ jobs
[1]+ Stopped vim myfile
然后您可以创建一个名为test.sh
的脚本,该脚本仅包含一个名为jobs
的命令.添加执行权限(例如chmod 700 test.sh
),然后启动它:
$ cat test.sh
jobs
~/dev/fi [3:1]$ ./test.sh
~/dev/fi [3:1]$ . ./test.sh
[1]+ Stopped vim myfile
在第一个版本中,创建了一个新的 bash 会话中未列出任何作业.但是,使用.
脚本可以在当前的bash 脚本中只有一个挂起进程(即vim
).因此,请使用.
启动上面的脚本,以免子级 bash 将被创建.
请注意,定义任何变量或更改目录(以及更多)会影响您的环境!例如.通过调用 bash 的问题,PID将可见! >
评论:
- 请勿使用
...|grep ...|grep -v ... |awk ---
弯管蛇!改用...|awk...
! - 在大多数Linux-es中,您可以使用类似
ps -o pid= -C pcmAppBin
的方法来获取pid,因此可以避免使用完整的管道. - 要从 awk 的问题中调用外部程序,您可以尝试
system("mycmd");
内置
我希望这会有所帮助!
I have a script that has to kill a certain number of times a resource managed by a high avialability middelware. It basically checks whether the resource is running and kills it afterwards, i need the timestamp of when the proc is really killed. So i have done this code:
#!/bin/bash
echo "$(date +"%T,%N") :New measures Run" > /home/hassan/logs/measures.log
for i in {1..50}
do
echo "Iteration: $i"
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
if [ -n "$PID" ]; then
echo "$(date +"%T,%N") :Killing $PID" >> /home/hassan/logs/measures.log
ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print "kill -9 " $2'} | sh
wait $PID
else
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
until [ -n "$PID" ]; do
sleep 2
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
done
fi
done
But with my wait command i get the following error message: wait: pid xxxx is not a child of this shell
I assume that You started the child processes from bash and then start this script to wait for. The problem is that the child processes are not the children of the bash running the script, but the children of its parent!
If You want to launch a script inside the the current bash You should start with .
.
An example. You start a vim
and then You make is stop pressing ^Z
(later you can use fg
to get back to vim
). Then You can get the list of jobs by using the˙jobs
command.
$ jobs
[1]+ Stopped vim myfile
Then You can create a script called test.sh
containing just one command, called jobs
. Add execute right (e.g. chmod 700 test.sh
), then start it:
$ cat test.sh
jobs
~/dev/fi [3:1]$ ./test.sh
~/dev/fi [3:1]$ . ./test.sh
[1]+ Stopped vim myfile
As the first version creates a new bash session no jobs are listed. But using .
the script runs in the present bash script having exactly one chold process (namely vim
). So launch the script above using the .
so no child bash will be created.
Be aware that defining any variables or changing directory (and a lot more) will affect to your environment! E.g. PID will be visible by the calling bash!
Comments:
- Do not use
...|grep ...|grep -v ... |awk ---
pipe snakes! Use...|awk...
instead! - In most Linux-es you can use something like this
ps -o pid= -C pcmAppBin
to get just the pid, so the complete pipe can be avoided. - To call an external program from awk you could try
system("mycmd");
built-in
I hope this helps a bit!
这篇关于我可以等待不是当前Shell终端的子进程的进程终止吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!