Bash 终止shell脚本时终止运行的命令
出于测试目的,我有这个shell脚本Bash 终止shell脚本时终止运行的命令,bash,Bash,出于测试目的,我有这个shell脚本 #!/bin/bash echo $$ find / >/dev/null 2>&1 从交互式终端运行此命令时,ctrl+c将终止bash,并终止find命令 $ ./test-k.sh 13227 <Ctrl+C> $ ps -ef |grep find $ 我希望此shell脚本在退出时终止其所有子进程,而不管如何调用它。它最终将从python和java应用程序开始—脚本退出时需要某种形式的清理—我应该研究哪些选项,或
#!/bin/bash
echo $$
find / >/dev/null 2>&1
从交互式终端运行此命令时,ctrl+c将终止bash,并终止find命令
$ ./test-k.sh
13227
<Ctrl+C>
$ ps -ef |grep find
$
我希望此shell脚本在退出时终止其所有子进程,而不管如何调用它。它最终将从python和java应用程序开始—脚本退出时需要某种形式的清理—我应该研究哪些选项,或者重写脚本以在退出时清理自身?您需要做的是捕获kill信号,终止find命令并退出。只需在脚本中添加一行如下内容:
trap "kill $$" SIGINT
您可能需要在设置中将'SIGINT'更改为'INT',但当您点击Ctrl-C时,这将基本上杀死您的进程和所有子进程。向组发送信号。 因此,与其杀死13231,不如:
kill -- -13231
如果您是从python开始的,请看一下:
这显示了如何在启动时模拟外壳
杀了一群人,我会这样做:
#!/bin/bash
trap : SIGTERM SIGINT
echo $$
find / >/dev/null 2>&1 &
FIND_PID=$!
wait $FIND_PID
if [[ $? -gt 128 ]]
then
kill $FIND_PID
fi
我想应该有一些解释。走出大门,我们需要改变一些默认的信号处理:
是一个no-op命令,因为传递一个空字符串会导致shell忽略该信号,而不是对其进行处理(与我们想要做的相反)
然后,在后台运行find
命令(从脚本的角度来看),我们调用wait
内置命令,等待它完成。由于我们向上面的trap
发出了一个实际命令,因此当处理信号时,wait
将以大于128的状态退出。如果进程wait
ed for完成,wait
将返回该进程的退出状态
最后,如果wait
返回错误状态,我们希望kill
子进程。幸运的是我们保存了它的PID。这种方法的优点是,您可以记录一些错误消息,或者以其他方式识别导致脚本退出的信号
正如其他人提到的,如果您不在乎在退出后留下任何信息,那么将kill--$$
作为trap
的参数是另一种选择
要使trap
按您想要的方式工作,您确实需要将其与wait
配对,-bash
手册页上说“如果bash
正在等待命令完成并接收到设置了trap
的信号,则在命令完成之前不会执行trap
。”等待
是解决这个问题的方法
如果需要,还可以将其扩展到更多子进程。我并没有完全测试这个,但它似乎在这里工作
$ ./test-k.sh &
[1] 12810
12810
$ kill 12810
$ ps -ef | grep find
$
正在寻找解决此问题的优雅解决方案,并在其他地方找到了以下解决方案
trap 'kill -HUP 0' EXIT
我自己的手册页没有说明
0
的含义,但仔细研究,它似乎是指当前的流程组。由于脚本get是它自己的进程组,因此最终会向脚本的所有子进程(前台和后台)发送信号。@Patrick的回答几乎成功了,但如果当前shell的父进程在同一个组中,它就不起作用(它也会杀死父进程)
我发现这样更好:
trap'pkill-p$$”退出
有关更多信息,请参阅。
kill
默认情况下发送SIGTERM
SIGKILL
是不可捕获的。您可能应该向find命令的pid发送术语,而不是“kill$$”<代码>$代码>也许吧,不过你可能想要更好的控制。传统的no-op命令是“:
”。如果我在后台启动进程,那么它不会被终止。如果我不在后台启动它,那么生成的子进程确实会被终止。请注意这一点(以及我发现的大多数其他方法)的一个缺点:如果您终止-9,则不会执行父进程的清理。在某些情况下,作为一种解决方法,您可以让子脚本监视其父脚本的运行状况。此脚本中的每个命令是否都属于该进程组?如果从shell启动,则是,否则,您将需要像subProcess.py中那样开始。您并不总是能够控制脚本的终止方式。这应该是公认的答案。这似乎很有效(尝试使用ctrl-C终止脚本并关闭终端),但我担心隐藏的缺点。有谁愿意分享他的观点?建议一个类似的答案,但似乎更有力
trap 'kill -HUP 0' EXIT