Votre killcommande est à l'envers.
Comme de nombreuses commandes UNIX, les options commençant par un moins doivent venir en premier, avant les autres arguments.
Si vous écrivez
kill -INT 0
il voit l' -INToption comme une option et envoie SIGINTà 0(0 est un nombre spécial signifiant tous les processus dans le groupe de processus actuel).
Mais si vous écrivez
kill 0 -INT
il voit le 0, décide qu'il n'y a plus d'options, donc utilise SIGTERMpar défaut. Et envoie cela au groupe de processus actuel, comme si vous l'aviez fait
kill -TERM 0 -INT
(il essaierait également d'envoyer SIGTERMà -INT, ce qui provoquerait une erreur de syntaxe, mais il enverrait SIGTERMà0 premier, et n'atteint jamais aussi loin.)
Donc, votre script principal obtient un SIGTERMavant de pouvoir exécuter le waitetecho DONE .
Ajouter
trap 'echo got SIGTERM' TERM
au sommet, juste après
trap 'killall' INT
et l'exécuter à nouveau pour le prouver.
Comme le souligne Stéphane Chazelas, vos enfants issus de milieux ( process1, etc.) ignorerontSIGINT par défaut.
En tout cas, je pense que l'envoi SIGTERMaurait plus de sens.
Enfin, je ne sais pas s'il kill -process groupest garanti d'aller en premier aux enfants. Ignorer les signaux lors de l'arrêt peut être une bonne idée.
Essayez donc ceci:
#!/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