Tu killcomando está al revés.
Al igual que muchos comandos de UNIX, las opciones que comienzan con un signo menos deben aparecer primero, antes que otros argumentos.
Si tú escribes
kill -INT 0
ve el -INTcomo una opción y envía SIGINTa 0( 0es un número especial que significa todos los procesos en el grupo de procesos actual).
Pero si escribes
kill 0 -INT
ve el 0, decide que no hay más opciones, por lo que usa SIGTERMde forma predeterminada. Y envía que al grupo de proceso actual, lo mismo que si lo hizo
kill -TERM 0 -INT
(que también intente enviar SIGTERMa -INT, lo que provocaría un error de sintaxis, pero envía SIGTERMa 0la primera, y nunca llega tan lejos.)
Por lo tanto, su script principal está obteniendo un SIGTERMantes de ejecutar el waity echo DONE.
Añadir
trap 'echo got SIGTERM' TERM
en la parte superior, justo después
trap 'killall' INT
y ejecutarlo nuevamente para probar esto.
Como señala Stephane Chazelas, sus hijos en segundo plano ( process1, etc.) ignorarán SIGINTde forma predeterminada.
En cualquier caso, creo que enviar SIGTERMtendría más sentido.
Finalmente, no estoy seguro de si kill -process groupse garantiza ir primero a los niños. Ignorar las señales mientras se apaga puede ser una buena idea.
Así que prueba esto:
#!/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