Reputation: 53
I'm playing with bash and signal handlers and found one interesting thing. But I can't explain why it so.
For example, we have a script test.sh which do something and can handle SIGTERM:
trap 'echo "sig 15 rcvd" ' 15
trap 'echo "sig 10 rcvd" ' 10
while true
do
; do something
sleep 0.2
done
So, when I sent a few signals to this script:
kill -15 <pidof test.sh>; kill -10 <pidof test.sh>
I've got signal 10 received early than signal 15:
sig 10 rcvd
sig 15 rcvd
If I send 2 times signal 10 or 15 script printed only once it:
kill -15 <pidof test.sh>; kill -15 <pidof test.sh>
sig 15 rcvd
It's also strange: I suggest that it's because we have double signal to the same pid and only one signal will be sent to it. Or there are some other reasons for this behavior?
And the last interesting thing: Remove sleep from script and send a both signals:
test.sh
trap 'echo "sig 15 rcvd" ' 15
trap 'echo "sig 10 rcvd" ' 10
while true
do
; do something
done
and send some signals to this script:
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>;
I've got unexpected results:
sig 10 rcvd
sig 10 rcvd
sig 15 rcvd
sig 10 rcvd
sig 10 rcvd
So, could someone describe why this happened? Why bash(?) mix up signals/remove one signals and add additional others??
UPD: One more interesting thing. Script looks like:
trap 'echo "sig 15 rcvd"; exit ' 15
trap 'echo "EXIT"' EXIT
After kill -15 I have "sig 15 rcvd" and "EXIT". But if I send kill -15 two times EXIT handler doesn't executed:
sig 15 rcvd
sig 15 rcvd
Upvotes: 5
Views: 423
Reputation: 3666
You basic confusion is because you are expecting synchronous results from an asynchronous mechanism.
So, when I sent a few signals to this script:
kill -15 <pidof test.sh>; kill -10 <pidof test.sh>
I've got signal 10 received early than signal 15:
sig 10 rcvd sig 15 rcvd
Those signals aren't queued. You send the first one and it begins executing the signal 15 trap but then before it completes you immediately send signal 10. This second signal interrupts the execution of the first trap. Now it executes the second trap printing sig 10 rcvd
. When the second handler finishes it then resumes the first interrupted handler and prints sig 15 rcvd
.
If I send 2 times signal 10 or 15 script printed only once it:
kill -15 <pidof test.sh>; kill -15 <pidof test.sh> sig 15 rcvd
Signals are always temporarily ignored while their signal handler is executing. If any duplicate signals are received before the trap finishes then they will not be handled. This is standard posix signal handling behavior.
It should be evident how a combination of those two behaviors can explain why you wont be able to easily predict the order of the output in your other tests.
Upvotes: 3