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

Stu*_*erg 11 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
Run Code Online (Sandbox Code Playgroud)

输出:

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

PSk*_*cik 9

SIGINT并且SIGQUIT在后台进程中被忽略(除非它们在后面进行后台处理set -m).这是一个(奇怪的)POSIX要求(请参阅http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html或我的问题为什么shell会在后台进程中忽略SIGINT和SIGQUIT?有关详细信息).

此外,POSIX要求:

输入子shell时,除非仅包含单个陷阱命令的命令替换,否则应将未被忽略的陷阱设置为默认操作.

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