Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does trap / kill work in bash on Linux?

Tags:

bash

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?

like image 979
polyglot Avatar asked Jan 07 '13 13:01

polyglot


1 Answers

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>:

  • Both the script and sleep received SIGTERM
  • bash registered the signal, noticed that a trap was set for it, and queued the handler for future execution
  • sleep exited immediately
  • bash noted sleep's exit, and ran the trap handler

whereas with kill <script_PID>:

  • Only the script received SIGTERM
  • bash registered the signal, noticed that a trap was set for it, and queued the handler for future execution
  • sleep exited after 1000 seconds
  • bash noted sleep's exit, and ran the trap handler

Obviously, 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.

like image 122
Adrian Avatar answered Oct 12 '22 19:10

Adrian