gpt4 book ai didi

bash - 为什么 KILL 信号处理程序在我的子进程死亡时不执行

转载 作者:行者123 更新时间:2023-11-29 08:57:32 24 4
gpt4 key购买 nike

我已经将一些脚本从 ksh 迁移到 bash,并且我在 bash 中观察到非常奇怪的行为。我能够减少到一个非常短的片段。

echo first test
LC_ALL=C xclock &
Active_pid=$!

sleep 1

kill -9 $Active_pid
sleep 1

echo second test
LC_ALL=C xclock &
Active_pid=$!

sleep 1
trap "echo Signal SIGKILL caught" 9
kill -9 $Active_pid
sleep 1

输出是

first test
./mig_bash.sh: line 15: 4471 Killed LC_ALL=C xclock
second test

我的问题是第一个测试中跟踪的产生。我试图查看是否收到信号。通过反复试验,我编写了解决我问题的“第二个测试”。我不明白。这如何在不执行 echo Signal SIGKILL 的情况下删除第一个测试的痕迹?

我完全迷路了。

最佳答案

我在 bash 文档中找不到任何可以解释观察到的行为的内容,所以我转向了源代码。调试导致函数notify_of_job_status() . line that prints the message about a killed subprocess只有满足以下所有条件才能达到:

  1. 子进程已在作业表中注册(即尚未被否认)
  2. shell 不是以交互模式启动的
  3. 终止子进程的信号没有被困在父 shell 中(参见 signal_is_trapped (termsig) == 0 check)

演示:

$ cat test.sh 
echo Starting a subprocess
LC_ALL=C sleep 100 &
Active_pid=$!
case "$1" in
disown) disown ;;
trapsigkill) trap "echo Signal SIGKILL caught" 9 ;;
esac
sleep 1
kill -9 $Active_pid
sleep 1
echo End of script

$ # Demonstrate the undesired message
$ bash test.sh
Starting a subprocess
test.sh: line 14: 15269 Killed LC_ALL=C sleep 100
End of script

$ # Suppress the undesired message by disowning the child process
$ bash test.sh disown
Starting a subprocess
End of script

$ # Suppress the undesired message by trapping SIGKILL in the parent shell
$ bash test.sh trapsigkill
Starting a subprocess
End of script

$ # Suppress the undesired message by using an interactive shell
$ bash -i test.sh
Starting a subprocess
End of script

How this removes the trace of the first test without executing echo Signal SIGKILL ?

陷阱不会执行,因为 KILL 信号是由子进程接收的,而不是已为其设置陷阱的 shell 进程。陷阱对诊断的影响存在于 notify_of_job_status() 函数的(有点争议的)逻辑中。

关于bash - 为什么 KILL 信号处理程序在我的子进程死亡时不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46606999/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com