bash:为什么我不能在后台shell中为SIGINT设置陷阱?

时间:2017-09-05 19:01:24

标签: bash

这是一个简单的程序,可以注册两个trap处理程序,然后使用trap -p显示它们。然后它做同样的事情,但是在子背景过程中。

为什么后台进程会忽略SIGINT陷阱?

#!/bin/bash

echo "Traps on startup:"
trap -p
echo ""

trap 'echo "Received INT"' INT
trap 'echo "Received TERM"' TERM

echo "Traps set on parent:"
trap -p
echo ""

(
    echo "Child traps on startup:"
    trap -p
    echo ""

    trap 'echo "Child received INT"' INT
    trap 'echo "Child received TERM"' TERM

    echo "Traps set on child:"
    trap -p
    echo ""
) &

child_pid=$!
wait $child_pid

输出:

$ ./show-traps.sh
Traps on startup:

Traps set on parent:
trap -- 'echo "Received INT"' SIGINT
trap -- 'echo "Received TERM"' SIGTERM

Child traps on startup:

Traps set on child:
trap -- 'echo "Child received TERM"' SIGTERM

1 个答案:

答案 0 :(得分:8)

在后台进程中会忽略

SIGINTSIGQUIT(除非它们在set -m开启的背景下)。这是一个(奇怪的)POSIX要求(有关详细信息,请参阅http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html或我的问题Why do shells ignore SIGINT and SIGQUIT in backgrounded processes?)。

此外,POSIX要求:

  

输入子shell时,应忽略未被忽略的陷阱   设置为默认操作,但命令除外   替换只包含一个陷阱命令..

但是,即使你在重置后再次在子shell中设置INT处理程序,susbshel​​l也无法接收它,因为它被忽略了(你可以尝试它,或者你可以检查它信号忽略使用ps的掩码,例如)。