为什么当我的子进程死亡时,KILL信号处理程序没有执行

BOC*_*BOC 7 bash

我已经将一些脚本从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
Run Code Online (Sandbox Code Playgroud)

输出是

first test
./mig_bash.sh: line 15:  4471 Killed                  LC_ALL=C xclock
second test
Run Code Online (Sandbox Code Playgroud)

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

我完全迷失了.

Leo*_*eon 6

我在bash文档中找不到任何可以解释观察到的行为的内容,所以我转向了源代码.调试导致该功能notify_of_job_status().仅当满足以下所有条件时,才能到达打印有关已终止子进程的消息的行:

  1. 子进程在作业表中注册(即尚未disown-ed)
  2. shell未以交互模式启动
  3. 终止子进程的信号没有被困在父shell中(参见signal_is_trapped (termsig) == 0支票)

示范:

$ 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
Run Code Online (Sandbox Code Playgroud)

如何在不执行的情况下删除第一个测试的跟踪echo Signal SIGKILL?

由于KILL子进程接收到信号而不是已设置陷阱的shell进程,因此不执行陷阱.陷阱对诊断的影响在于notify_of_job_status()函数中的(有些可论证的)逻辑.