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

时间:2017-10-06 13:33:52

标签: 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

输出

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

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

我完全迷失了。

1 个答案:

答案 0 :(得分:6)

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

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

    $ 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
    
      

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

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