Your kill
command is backwards.
Like many UNIX commands, options that start with a minus must come first, before other arguments.
If you write
kill -INT 0
it sees the -INT
as an option, and sends SIGINT
to 0
(0
is a special number meaning all processes in the current process group).
But if you write
kill 0 -INT
it sees the 0
, decides there's no more options, so uses SIGTERM
by default. And sends that to the current process group, the same as if you did
kill -TERM 0 -INT
(it would also try sending SIGTERM
to -INT
, which would cause a syntax error, but it sends SIGTERM
to 0
first, and never gets that far.)
So your main script is getting a SIGTERM
before it gets to run the wait
and echo DONE
.
Add
trap 'echo got SIGTERM' TERM
at the top, just after
trap 'killall' INT
and run it again to prove this.
As Stephane Chazelas points out, your backgrounded children (process1
, etc.) will ignore SIGINT
by default.
In any case, I think sending SIGTERM
would make more sense.
Finally, I'm not sure whether kill -process group
is guaranteed to go to the children first. Ignoring signals while shutting down might be a good idea.
So try this:
#!/bin/bash
trap 'killall' INT
killall() {
trap '' INT TERM # ignore INT and TERM while shutting down
echo "**** Shutting down... ****" # added double quotes
kill -TERM 0 # fixed order, send TERM not INT
wait
echo DONE
}
./process1 &
./process2 &
./process3 &
cat # wait forever