Quick summary: parent and child in a loop, each can either trap or not trap signals. I don't understand why, if the child traps and the parent doesn't, the parent is not terminated.
I have two simple scripts, which just run a loop, and optionally trap SIGINT and other signals. The child script is launched by the parent.
#!/bin/bash parent_trap=$1 child_trap=$2 shutdown=0 (( parent_trap )) && trap "echo 'parent: caught signal'; shutdown=1" INT TERM HUP PIPE while (( ! shutdown )) ; do echo parent ./child $child_trap sleep 1 done
#!/bin/bash child_trap=$1 shutdown=0 (( child_trap )) && trap "echo 'child: caught signal'; shutdown=1" INT TERM HUP PIPE while (( ! shutdown )) ; do echo child sleep 1 done
When these are run with the four combinations of trapping signals:
$ ./parent 0 0 parent child child child ^C
parent and child are both terminated by ctrl-c. As I understand it, the shell sends SIGINT to all processes in the process group, there are no handlers, so the default action of terminate is invoked.
parent and child both trap:
$ ./parent 1 1 parent child child child ^Cchild: caught signal parent: caught signal
parent and child both catch signal and both exit cleanly
parent traps signal, child does not:
$ ./parent 1 0 parent child child child ^Cparent: caught signal
parent catches signal and exits cleanly. child is killed by terminate (I think)
child traps signal, parent does not:
$ ./parent 0 1 parent child child child ^Cchild: caught signal parent child ^Cchild: caught signal parent child ^Cchild: caught signal ^C
child traps signal and exits cleanly, but parent, which does not trap signal continues (relaunching child) until ctrl-c is pressed twice in quick succession.
Why isn't the parent terminated as the default action when there is no signal handler?