我在 shell 脚本中看到trap 'kill $(jobs -p)' EXIT
发送信号术语当该 shell 关闭时,执行该 shell 的所有作业。如果执行 bash 脚本,则会启动新的 bash shell。例如,这里用户执行./trap_test.sh
并创建一个带有 PID 的 bash 实例98959
:
| | |-+= 05624 user /usr/local/bin/bash
| | | \-+= 98959 user /bin/bash ./trap_test.sh
| | | \--- 98960 user sleep 10
在什么情况下,当父 shell 关闭时作业可能仍在运行?在上面的例子中,如果我杀死 PID 98959,那么 PID 98960 也会被自动杀死。trap 'kill $(jobs -p)' EXIT
对我来说似乎毫无用处,因为当外壳本身关闭时,所有子进程都应该被杀死。
答案1
如果子进程使用 nohup 启动,它将在父 shell 退出/死亡后继续存在,这就是 nohup 命令的目的。
另一种可能性是,如果脚本或进程处理终止信号(显然不是终止 -9)并忽略它,那么如果您将其作为后台任务启动,则当前 shell 退出时它不会死亡。
例子:
#!/bin/bash
function trap_handler
{
echo "SORRY! I am not going down MUAHAHA!"
}
trap trap_handler SIGINT SIGTERM SIGHUP
while true
do
sleep 60
done
因此,如果我将其作为后台任务启动并尝试终止它,则会发生以下情况:
$ ps -ef | grep test &
$ jobs
[1]+ Running ./test_trap.sh &
$ kill %1
$ Terminated
SORRY! I am not going down MUAHAH!
$ jobs
[1]+ Running ./test_trap.sh &
好的,现在让我们从另一个终端监视该进程,并观察当我退出启动脚本的终端/shell 时会发生什么:
$ pstree -clap 26163
bash,26163
└─test_trap.sh,26175 ./test_trap.sh
└─sleep,26183 60
## exited the original terminal window with exit
$ pstree -clap 26163
$
$ pstree -clap 26175
test_trap.sh,26175 ./test_trap.sh
└─sleep,26185 60
终端进程不再存在,但是当我对启动的 test_trap.sh 的进程 ID 执行 pstree 时,它及其子进程仍然存在。