Search code examples
bashshellsignalssigterm

SIGTERM signal handling confusion


I am running a program which invokes a shell script (for discussion sh1 with pid 100). This script in turn invokes another script (for discussion sh2 with pid 101) and waits for it to finish. sh2(child script) takes about 50 seconds to finish.

The way I invoke the sh2 (/bin/sh2.sh )

During waiting for child to be done, I try to Terminate sh1 (using kill -15 100). I have a handler function in sh1 to handle this signal. However, I observe that my sh1(parent script) doesnot get terminated till the child is done with its work (for 50 seconds) and only after that this Signal is handled.

I modified my child script, to take 30 seconds to finish and I observe that after issuing the SIGTERM to sh1, it then takes around 30 seconds to terminate.

Is this the behavior while handling the SIGTERM ? that is to remain blocked by the child process ? and only then handle the signal. Doesn't the process get interrupted for signal handling?

SIGNAL Handling in parent script.

function clean_up()
{   
  //Do the cleanup
}

trap "clean_up $$; exit 0" TERM

Solution

  • If sh1 invokes sh2 and waits for it to finish, then it doesn't run the trap for the signal until after sh2 finishes. That is, if this is sh1:

    #!/bin/sh  
    trap 'echo caught signal delayed' SIGTERM
    sh2
    

    then sh1 will catch the signal and do nothing until sh2 finishes, and then it will execute the trap. If you want the trap to fire as soon as the signal is sent, you can run sh2 asynchronously and wait for it explicitly:

    #!/bin/sh
    trap 'echo caught signal' SIGTERM
    sh2&
    wait
    

    Unfortunately, this doesn't re-enter the wait. If you need to continue waiting, it's not really possible to do reliably, but you can get close with:

    #!/bin/sh
    trap 'echo caught signal' SIGTERM
    sh2&
    (exit 129)   # prime the loop (eg, set $?) to simulate do/while
    while test $? -gt 128; do wait; done
    

    This isn't reliable because you can't tell the difference between catching a signal yourself and sh2 being terminated by a signal. If you need this to be reliable, you should re-write sh1 in a language which allows better control of signals.