当我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>)。