$ bash -c "trap \"echo INT\" INT; sleep 3" & pid=$!; sleep 1; kill -INT $pid; wait
[1] 27811
INT
[1]+ Done bash -c "trap \"echo INT\" INT; sleep 3"
$ (bash -c "trap \"echo INT\" INT; sleep 3" & pid=$!; sleep 1; kill -INT $pid; wait)
你能解释一下为什么SIGINT
处理程序在第二种情况下没有被调用吗?
https://www.gnu.org/software/libc/manual/html_node/Job-Control.html
通常它在交互式 shell 中启用,在非交互式 shell 中禁用:
在这种情况下......显然工作控制被禁用,
$-
不能依赖:https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html
也就是说,当启用作业控制时,每个管道都在单独的进程组中执行。
pgid.sh
:其中一项工作是前台工作,其余工作是后台工作。
后台作业不应该绑定到启动它们的 shell。如果您退出 shell,它们将继续运行。因此,它们不应该被 打断
SIGINT
,而不是默认情况下。当启用作业控制时,会自动完成,因为后台作业在单独的进程组中运行。当作业控制被禁用时,bash
使异步命令忽略SIGINT
,并且不让它们(如果它们是bash
脚本)覆盖它。也就是说,这里:
后台作业 (
bash -c "trap 'echo INT' INT; sleep 3"
) 由启用了作业控制的交互式 shell 执行。结果,后台作业收到SIGINT
.当我们将它包装到一个没有作业控制的非交互式 shell 中时:
bash -c "trap 'echo INT' INT; sleep 3"
忽略SIGINT
,trap ... INT
也被忽略。可以这样确认:
一些相关的报价:
https://www.gnu.org/software/bash/manual/html_node/Signals.html
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-trap
https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html