为什么 sleep 在 shell 脚本中运行时会忽略 SIGINT?

mpb*_*mpb 7 shell sleep shell-script sigint

当我sleep手动运行,然后kill -INT它,睡眠立即退出。例如:

$  /bin/sleep  60  &
[1] 4002356
$  kill -INT 4002356
[1]+  Interrupt               /bin/sleep 60
$  ps -C sleep
    PID TTY          TIME CMD
$  
Run Code Online (Sandbox Code Playgroud)

但是,当我在 shell 脚本中做同样的事情时,会sleep忽略SIGINT. 例如:

set  -o xtrace

echo
/bin/sleep  10  &
child="$!"
/bin/sleep  0.1
ps -C sleep
kill  -TERM  "$child"    #  SIGTERM                                         
/bin/sleep  0.1
ps -C sleep
wait  "$child"    #  will return immediately                                

echo
/bin/sleep  10  &
child="$!"
/bin/sleep  0.1
ps -C sleep
kill  -INT  "$child"    #  SIGINT
/bin/sleep  0.1
ps -C sleep
wait  "$child"    #  will wait for 9.8 seconds                              
Run Code Online (Sandbox Code Playgroud)

SIGINT当我sleep在 shell 脚本中运行时,为什么/如何忽略睡眠?

我得到与dash和相同的行为bash。我的内核是 Linux 5.4.0。

Kam*_*ski 10

/bin/sleep 10 &终止时&使外壳sleep异步运行。默认情况下,在脚本中禁用作业控制。在 Bash 中,以下内容适用 [强调我的]:

由 Bash 启动的非内置命令将信号处理程序设置为 shell 从其父级继承的值。当作业控制无效时,除了这些继承的处理程序之外,异步命令还会忽略 SIGINT和 SIGQUIT。

来源:Bash 参考手册

并且相关地,SIG_IGN在对 的调用中持续存在execv(),可能的例外是SIGCHLD

在调用进程映像中设置为默认操作(SIG_DFL)的信号应设置为新进程映像中的默认操作。除了 SIGCHLD,调用进程映像设置为忽略的信号 (SIG_IGN) 应设置为新进程映像忽略。设置为由调用进程映像捕获的信号应设置为新进程映像中的默认操作(参见 <signal.h>)。

来源:开放组基本规范第 7 期,2018 年版