bash - 当 shell 脚本被杀死时终止正在运行的命令

标签 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 将孤立脚本中运行的命令。

$ ./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。这种方法的优点是您可以记录一些错误消息或以其他方式识别导致脚本退出的信号。

正如其他人所提到的,如果您不关心在 post-导出。

要使 trap 以您想要的方式工作,您需要将其与 wait 配对 - bash 手册页说“如果bash 正在等待命令完成并接收到已为其设置了 trap 的信号,trap 将不会执行,直到命令完成。” wait 是解决这个问题的方法。

如果需要,您也可以将其扩展到更多子进程。我并没有真正详尽地测试这个,但它似乎在这里工作。

$ ./test-k.sh &
[1] 12810
12810
$ kill 12810
$ ps -ef | grep find
$

关于bash - 当 shell 脚本被杀死时终止正在运行的命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1644856/

相关文章:

linux - Gstreamer:从 stdout 读取原始图像并将其转换为 h264 流

android - 从 Shell 脚本安装 APK 并启动应用程序

mysql - 将 schema.sql 注入(inject) mysql 数据库的 bash 脚本命令

c - 在 Bash 脚本中运行 C 程序

提供包含波形符 (~) 的路径变量时,bash diff 无法找到现有文件

mysql - 无法在 nix mysql CLI 中更改 mysql 密码

python - 如何将参数重复传递给 python 文件

bash - 让其他用户停止/重启简单的 bash 守护进程——使用信号还是什么?

php - 为什么 PHP 挂起,当 bash 调用 fork 时

bash - 终端 Tab 键不会自动完成,而是尝试运行我的脚本