【发布时间】:2016-06-04 12:52:03
【问题描述】:
我正在使用 bash 和信号处理程序并发现一件有趣的事情。但我无法解释为什么会这样。
例如,我们有一个脚本 test.sh 可以做一些事情并且可以处理 SIGTERM:
trap 'echo "sig 15 rcvd" ' 15
trap 'echo "sig 10 rcvd" ' 10
while true
do
; do something
sleep 0.2
done
所以,当我向这个脚本发送一些信号时:
kill -15 <pidof test.sh>; kill -10 <pidof test.sh>
我收到的信号 10 比信号 15 早:
sig 10 rcvd
sig 15 rcvd
如果我发送 2 次信号 10 或 15 脚本只打印一次:
kill -15 <pidof test.sh>; kill -15 <pidof test.sh>
sig 15 rcvd
这也很奇怪:我建议这是因为我们对同一个 pid 有双重信号,并且只会向它发送一个信号。或者这种行为还有其他一些原因?
最后一件有趣的事:从脚本中移除 sleep 并发送两个信号:
test.sh
trap 'echo "sig 15 rcvd" ' 15
trap 'echo "sig 10 rcvd" ' 10
while true
do
; do something
done
并向该脚本发送一些信号:
kill -10 <pidof test.sh>; kill -15 <pidof test.sh>;\
kill -10 <pidof test.sh>; kill -10 <pidof test.sh>;\
kill -15 <pidof test.sh>;
我得到了意想不到的结果:
sig 10 rcvd
sig 10 rcvd
sig 15 rcvd
sig 10 rcvd
sig 10 rcvd
那么,有人能描述一下为什么会这样吗?为什么 bash(?) 会混淆信号/删除一个信号并添加其他信号??
UPD:还有一件有趣的事情。脚本如下:
trap 'echo "sig 15 rcvd"; exit ' 15
trap 'echo "EXIT"' EXIT
在 kill -15 之后,我有“sig 15 rcvd”和“EXIT”。 但是如果我发送 kill -15 两次 EXIT 处理程序不会执行:
sig 15 rcvd
sig 15 rcvd
【问题讨论】:
-
这很有趣。您能否尝试将
;替换为&&并查看您得到的输出类型?只有在statement1成功后才会执行statement2。 -
嘿,还有一个意想不到的结果:我有 sig 10; 15号;签名 10; sig 10 就是这样。最后 sig 15 未处理 :)
-
这只是一个猜测,我对此并不完全确定,但这是我的两分钱:kill 也是一个内置的 shell(当然是 bash)所以当你在没有路径的情况下运行 kill 时,它是可能的shell 将使用内部 kill 并且这样做可以优化如果重复发送相同的信号。实际的 kill 二进制可执行文件(对于大多数系统可能在 /bin/kill 中)发送一个信号,因此内核将接收它并通知接收进程......它自己可以解释信号到达的顺序与你的不同可能会期待。