Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signal handling in a shell script

Following is a shell script (myscript.sh) I have:

#!/bin/bash

sleep 500 &

Aprogram arg1 arg2  # Aprogram is a program which runs for an hour.

echo "done"

I launched this in one terminal, and from another terminal I issued 'kill -INT 12345'. 12345 is the pid of myscript.sh.

After a while I can see that both myscript.sh and Aprogram have been dead. However 'sleep 500 &' is still running.

Can anyone explain why is this behavior?

Also, when I issued SIGINT signal to the 'myscript.sh' what exactly is happening? Why is 'Aprogram' getting killed and why not 'sleep' ? How is the signal INT getting transmitted to it's child processes?

like image 864
ernesto Avatar asked Apr 04 '14 06:04

ernesto


2 Answers

You start sleep in the background. As such, it is not killed when you kill the script.

If you want to kill sleep too when the script is terminated, you'd need to trap it.

sleep 500 &
sid=($!)                   # Capture the PID of sleep
trap "kill ${sid[@]}" INT   # Define handler for SIGINT

Aprogram arg1 arg2 & # Aprogram is a program which runs for an hour.
sid+=($!)
echo "done"

Now sending SIGINT to your script would cause sleep to terminate as well.

like image 177
devnull Avatar answered Sep 30 '22 04:09

devnull


You need to use trap to catch signals:

To just ignore SIGINT use:

trap '' 2

if you want to specify some special action for this you can make it that in line:

trap 'some commands here' 2

or better wrap it into a function

function do_for_sigint() {
 ...
}

trap 'do_for_sigint' 2

and if you wish to allow your script to finish all it's tasks first:

keep_running="yes"

trap 'keep_running="no"' 2

while [ $keep_running=="yes" ]; do
 # main body of your script here
done
like image 31
pawel7318 Avatar answered Sep 30 '22 04:09

pawel7318