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

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

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

$  /bin/sleep  60  &
[1] 4002356
$  kill -INT 4002356
[1]+  Interrupt               /bin/sleep 60
$  ps -C sleep
    PID TTY          TIME CMD
$  

但是,当我在 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                              

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

dash我对和 也有同样的行为bash。我的内核是Linux 5.4.0。

答案1

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

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

来源:Bash 参考手册

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

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

来源:The Open Group 基本规范第 7 期,2018 年版

相关内容