父进程收到SIGINT后不执行默认操作

父进程收到SIGINT后不执行默认操作

我在 bash 中使用Ctrl+做了 2 个关于 SIGINT 的测试。C

测试1

父脚本和子脚本都通过 来设置处理程序trap

# !/bin/bash
# Parent.sh
trap 'echo "I handled the SIGINT in Parent.sh and expect the script going ahead."' SIGINT
echo 1.1
./Child.sh
echo 1.2
# !/bin/bash
# Child.sh
trap 'echo "I handled the SIGINT in Child.sh and expect the script going ahead."' SIGINT
echo 2.1
sleep 1000000000
echo 2.2
/tmp:$ ./Parent.sh
1.1
2.1
^CI handled the SIGINT in Child.sh and expect the script going ahead.
2.2
I handled the SIGINT in Parent.sh and expect the script going ahead.
1.2

输出结果非常符合我的预期。

测试2

只有子脚本通过 设置处理程序trap

# !/bin/bash
# Parent.sh
# trap 'echo "I expect I will be terminated immediately after Child.sh died."' SIGINT
echo 1.1
./Child.sh
echo "sleep started"
sleep 5
echo "sleep finished"
echo 1.2
# !/bin/bash
# Child.sh
trap 'echo "I handled the SIGINT in Child.sh and expect the script going ahead."' SIGINT
echo 2.1
sleep 1000000000
echo 2.2
/tmp:$ ./Parent.sh
1.1
2.1
^CI handled the SIGINT in Child.sh and expect the script going ahead.
2.2
sleep started
sleep finished
1.2

我预计死后Parent.sh应该立即终止(作为关于 SIGINT 的默认操作)Child.sh

但它似乎Parent.sh收到了一个 SIGINT,但它忽略了它。

为什么会是这样呢?

答案1

发生这种情况是因为《等待并配合退出》(WCE)bash实施。

当 bashSIGINT在等待子进程时收到信号时,只有当子进程因该信号而死亡时(而不是子进程退出时),它才会自杀。父WIF*进程可以根据子进程的退出状态确定它是由于未处理的信号而退出还是死亡 - 请参阅wait(2)联机帮助页。

一个更简单的例子:

bash -c 'sh -c "trap exit INT; read p"; echo DONE'
<ctrl-C>
DONE

并与dashshell,它不实现 WCE:

dash -c 'sh -c "trap exit INT; read p"; echo DONE'
<ctrl-C>
<no DONE, parent script was killed outright>

看看类似的问答,以及拼凑我建议作为一种解决方法。

相关内容