终止正在运行的命令时,shell脚本被杀害
出于测试目的,我有这个shell脚本终止正在运行的命令时,shell脚本被杀害
#!/bin/bash
echo $$
find/>/dev/null 2>&1
从交互终端,CTRL + C运行,这将终止庆典,并find命令。
$ ./test-k.sh
13227
<Ctrl+C>
$ ps -ef |grep find
$
运行在后台,杀壳只会孤立在脚本执行上面的命令。
$ ./test-k.sh &
[1] 13231
13231
$ kill 13231
$ ps -ef |grep find
nos 13232 1 3 17:09 pts/5 00:00:00 find/
$
我希望这个shell脚本在退出时终止它的所有子进程,而不管它如何被调用。它最终将从一个python和java应用程序开始 - 当脚本退出时需要某种形式的清理 - 我应该查看的任何选项或以任何方式重写脚本以在退出时自行清理?
我会做这样的事情:
#!/bin/bash
trap : SIGTERM SIGINT
echo $$
find/>/dev/null 2>&1 &
FIND_PID=$!
wait $FIND_PID
if [[ $? -gt 128 ]]
then
kill $FIND_PID
fi
一些解释是为了,我猜。走出门外,我们需要改变一些默认的信号处理。 :
是一个没有操作的命令,因为传递一个空字符串会导致shell忽略信号而不是做一些事情(与我们想做的事情相反)。
然后,find
命令在后台运行(从脚本的角度来看),我们称之为wait
内置完成。由于我们给出了上述trap
的实际命令,因此当处理信号时,wait
将以大于128的状态退出。如果完成进程wait
,则wait
将返回该进程的退出状态。
最后,如果wait
返回那个错误状态,我们想要kill
这个子进程。幸运的是我们保存了它的PID。这种方法的优点是您可以记录一些错误信息或以其他方式识别信号导致脚本退出。
正如其他人所说的,如果您不关心在退出后留下任何信息,另一种选择是kill -- -$$
作为trap
的参数。
对于trap
工作,你想要的方式,你需要与wait
配对起来 - 在bash
手册页说:“如果bash
正在等待命令完成并收到其中trap
已设置的信号,直到命令完成,trap
才会被执行。“ wait
就是绕过这个呃逆。
如果您愿意,也可以将其扩展到更多子进程。我没有真正详尽地测试这一个,但它似乎在这里工作。
$ ./test-k.sh &
[1] 12810
12810
$ kill 12810
$ ps -ef | grep find
$
你需要做的事情是陷阱kill信号,杀死查找命令并退出。
'kill'默认发送'SIGTERM'。 'SIGKILL'不可捕捉。 – 2009-10-29 16:34:55
就这样添加一行脚本:
trap "kill $$" SIGINT
您可能需要更改“SIGINT”到你的设置“INT”,但这基本上会杀了你的进程和所有子进程,当你按Ctrl-C。
而不是'kill $$',你可能应该将TERM发送给find命令的pid! – 2009-10-29 16:41:49
'$!'也许,虽然你可能想要比这更好的控制。 – ephemient 2009-10-29 17:23:30
发送信号给组。 所以不是kill 13231
做:
kill -- -13231
如果你从蟒蛇开始,然后看看: http://www.pixelbeat.org/libs/subProcess.py 展示了如何模仿壳开始 和杀害一组
正在寻找这个问题的优雅解决方案,并在其他地方找到了以下解决方案。
trap 'kill -HUP 0' EXIT
我自己的手册页说什么什么0
手段,但是从周围挖掘,这似乎意味着当前进程组。由于脚本得到了它自己的进程组,所以最终将SIGHUP发送给所有脚本的子进程,前台和后台。
传统的无操作命令是“':'”。 – ephemient 2009-10-29 17:21:27
很热。现在改变它。 – 2009-10-29 17:30:25
如果我在后台启动进程,那么它不会被杀死。如果我不在后台启动,生成的子进程确实会被杀死 – 2011-06-14 20:32:53