快速总结:父级和子级处于循环中,每个都可以捕获或不捕获信号。我不明白为什么,如果孩子陷入困境而父母没有陷入困境,则父母不会被终止。
细节:
我有两个简单的脚本,它们只运行一个循环,并且可以选择捕获 SIGINT 和其他信号。子脚本由父脚本启动。
家长:
#!/bin/bash
parent_trap=$1
child_trap=$2
shutdown=0
(( parent_trap )) && trap "echo 'parent: caught signal'; shutdown=1" INT TERM HUP PIPE
while (( ! shutdown )) ; do
echo parent
./child $child_trap
sleep 1
done
孩子:
#!/bin/bash
child_trap=$1
shutdown=0
(( child_trap )) && trap "echo 'child: caught signal'; shutdown=1" INT TERM HUP PIPE
while (( ! shutdown )) ; do
echo child
sleep 1
done
当这些与捕获信号的四种组合一起运行时:
无陷阱:
$ ./parent 0 0
parent
child
child
child
^C
父进程和子进程都由 ctrl-c 终止。据我了解,shell向进程组中的所有进程发送SIGINT,没有处理程序,因此调用终止的默认操作。
父母和孩子都陷入困境:
$ ./parent 1 1
parent
child
child
child
^Cchild: caught signal
parent: caught signal
父级和子级都捕获信号并且都干净地退出
父级捕获信号,子级不捕获:
$ ./parent 1 0
parent
child
child
child
^Cparent: caught signal
父进程捕获信号并干净地退出。孩子被终止杀死(我认为)
子进程捕获信号,父进程不捕获信号:
$ ./parent 0 1
parent
child
child
child
^Cchild: caught signal
parent
child
^Cchild: caught signal
parent
child
^Cchild: caught signal
^C
子进程捕获信号并干净地退出,但不捕获信号的父进程继续(重新启动子进程),直到快速连续按两次 ctrl-c 为止。
当没有信号处理程序时,为什么父级不作为默认操作终止?