My sample file
traptest.sh:
#!/bin/bash
trap 'echo trapped' TERM
while :
do
sleep 1000
done
$ traptest.sh &
[1] 4280
$ kill %1 <-- kill by job number works
Terminated
trapped
$ traptest.sh &
[1] 4280
$ kill 4280 <-- kill by process id doesn't work?
(sound of crickets, process isn't killed)
If I remove the trap statement completely, kill process-id works again?
Running some RHEL 2.6.18-194.11.4.el5 at work. I am really confused by this behaviour, is it right?
Davide Berra explained the difference between kill %<jobspec>
and kill <PID>
, but not how that difference results in what you observed. After all, Unix signal handlers should be called pretty much instantaneously, so why does sending a SIGTERM
to the script alone not trigger its trap handler?
The bash
man page explains why, in the last paragraph of the SIGNALS section:
If
bash
is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
So, the signal was delivered immediately, but the handler execution was deferred until sleep
exited.
Hence, with kill %<jobspec>
:
sleep
received SIGTERM
bash
registered the signal, noticed that a trap
was set for it, and queued the handler for future executionsleep
exited immediatelybash
noted sleep
's exit, and ran the trap handlerwhereas with kill <script_PID>
:
SIGTERM
bash
registered the signal, noticed that a trap
was set for it, and queued the handler for future executionsleep
exited after 1000 seconds
bash
noted sleep
's exit, and ran the trap handlerObviously, you didn't want long enough to see that last bit. :)
If you're interested in the gory details, download the bash
source code and look in trap.c
, specifically the trap_handler()
and run_pending_traps()
functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With