Question

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?

Was it helpful?

Solution 3

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

As soon as Aprogram is finished myscript.sh prints "Done" and is also finised. sleep 500 gets process with PID 1 as a parent. That is it.

Can anyone explain why is this behavior?

SIGINT is not deliverd to Aprogram when myscript.sh gets it. Use strace to make sure that Aprogram does not receive a signal.

Also, when I issued SIGINT signal to the 'myscript.sh' what exactly is happening?

I first thought that it is the situation like when a user presses Ctrl-C and read this http://www.cons.org/cracauer/sigint.html. But it is not exactly the same situation. In your case shell received SIGINT but the child process didn't. However, shell had at that moment a child process and it did not do anything and kept waiting for a child. This is strace output on my computer after sending SIGINT to a shell script waiting for a child process:

>strace -p 30484
Process 30484 attached - interrupt to quit
wait4(-1, 0x7fffc0cd9abc, 0, NULL)      = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---
rt_sigreturn(0x2)                       = -1 EINTR (Interrupted system call)
wait4(-1,

Why is 'Aprogram' getting killed and why not 'sleep' ? How is the signal INT getting transmitted to it's child processes?

As far as I can see with strace a child program like your Aprogram is not getting killed. It did not receive SIGINT and finished normally. As soon as it finished your shell script also finished.

OTHER TIPS

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top