nea*_*lon 5 linux bash shell signals
我正在使用 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
Run Code Online (Sandbox Code Playgroud)
因此,当我向该脚本发送一些信号时:
kill -15 <pidof test.sh>; kill -10 <pidof test.sh>
Run Code Online (Sandbox Code Playgroud)
我收到的信号 10 早于信号 15:
sig 10 rcvd
sig 15 rcvd
Run Code Online (Sandbox Code Playgroud)
如果我发送 2 次信号 10 或 15 脚本仅打印一次:
kill -15 <pidof test.sh>; kill -15 <pidof test.sh>
sig 15 rcvd
Run Code Online (Sandbox Code Playgroud)
这也很奇怪:我认为这是因为我们对同一个 pid 有双重信号,并且只有一个信号会发送给它。或者还有其他一些原因导致这种行为?
最后一件有趣的事情:从脚本中删除睡眠并发送两个信号:
test.sh
trap 'echo "sig 15 rcvd" ' 15
trap 'echo "sig 10 rcvd" ' 10
while true
do
; do something
done
Run Code Online (Sandbox Code Playgroud)
并向该脚本发送一些信号:
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>;
Run Code Online (Sandbox Code Playgroud)
我得到了意想不到的结果:
sig 10 rcvd
sig 10 rcvd
sig 15 rcvd
sig 10 rcvd
sig 10 rcvd
Run Code Online (Sandbox Code Playgroud)
那么,有人可以描述为什么会发生这种情况吗?为什么 bash(?) 混合信号/删除一个信号并添加其他信号?
UPD:还有一件有趣的事情。脚本看起来像:
trap 'echo "sig 15 rcvd"; exit ' 15
trap 'echo "EXIT"' EXIT
Run Code Online (Sandbox Code Playgroud)
在kill -15之后,我有“sig 15 rcvd”和“EXIT”。但是如果我发送kill -15 两次 EXIT 处理程序不会执行:
sig 15 rcvd
sig 15 rcvd
Run Code Online (Sandbox Code Playgroud)
您的基本困惑是因为您期望异步机制产生同步结果。
因此,当我向该脚本发送一些信号时:
Run Code Online (Sandbox Code Playgroud)kill -15 <pidof test.sh>; kill -10 <pidof test.sh>我收到的信号 10 早于信号 15:
Run Code Online (Sandbox Code Playgroud)sig 10 rcvd sig 15 rcvd
这些信号没有排队。您发送第一个信号,它就会开始执行信号 15 陷阱,但在完成之前您立即发送信号 10。第二个信号会中断第一个陷阱的执行。现在它执行第二次陷阱打印sig 10 rcvd。当第二个处理程序完成时,它会恢复第一个中断的处理程序并打印sig 15 rcvd。
如果我发送 2 次信号 10 或 15 脚本仅打印一次:
Run Code Online (Sandbox Code Playgroud)kill -15 <pidof test.sh>; kill -15 <pidof test.sh> sig 15 rcvd
当信号处理程序执行时,信号总是被暂时忽略。如果在陷阱完成之前收到任何重复信号,则不会对其进行处理。这是标准的 posix 信号处理行为。
很明显,这两种行为的组合可以解释为什么您无法轻松预测其他测试中的输出顺序。