2

I have a following bash script:

#!/bin/bash
for i in {0..8}
do
  trap "echo received $i" $i
done
trap "echo 'receiving the SIGINT'; kill -9  $$" INT
for i in {10..64}
do
  trap "echo receiving the $i" $i
done

sleep 1h

If run it and from other terminal send the SIGINT to it, it does nothing. I am using kill -2 pid where pid is the pid of the running script.

If I hit CTRL+C (SIGINT) in terminal where the script is running it kills itself and writes the message. How come, it is not the same when sending the signal to it from a different terminal?

Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72
  • Related: http://stackoverflow.com/questions/14696427/how-can-bash-script-do-the-equivalent-of-ctrl-c-to-a-background-task/14697034#14697034 – user000001 Feb 14 '13 at 17:21

2 Answers2

0

If I replace the sleep 1h with the

while true ; do
    sleep 1
done

It is working :-)

Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72
0

Generally, the shell delivers handled signals ("springs a trap") only between commands. This means that your script's INT trap cannot spring until the child sleep process has exited.

In the CTRL+C case, the terminal sends a SIGINT to the foreground process group. This group includes both your_script.sh and its child sleep 1h. The child process is killed immediately, and then the script unblocks and springs the trap for the signal it received, too.

In the kill -INT case, the SIGINT is delivered only to your_script.sh but not to its child, so the trap is held pending until the child exits normally. That's why reducing the sleep interval from 1 hour to a tight loop of 1 second periods works: the trap is pending for no more than 1 second.

pilcrow
  • 56,591
  • 13
  • 94
  • 135