Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 终止shell脚本时终止运行的命令_Bash - Fatal编程技术网

Bash 终止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应用程序开始—脚本退出时需要某种形式的清理—我应该研究哪些选项,或

出于测试目的,我有这个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应用程序开始—脚本退出时需要某种形式的清理—我应该研究哪些选项,或者重写脚本以在退出时清理自身?

您需要做的是捕获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