Il tuo killcomando è al contrario.
Come molti comandi UNIX, le opzioni che iniziano con un segno meno devono venire prima, prima di altri argomenti.
Se scrivi
kill -INT 0
vede l' -INTopzione come e invia SIGINTa 0( 0è un numero speciale che significa tutti i processi nel gruppo di processi corrente).
Ma se scrivi
kill 0 -INT
vede il 0, decide che non ci sono più opzioni, quindi utilizza SIGTERMper impostazione predefinita. E manda che al gruppo processo corrente, lo stesso come se avete fatto
kill -TERM 0 -INT
(proverebbe anche a inviarlo SIGTERMa -INT, il che provocherebbe un errore di sintassi, ma invia SIGTERMper 0primo e non arriva mai così lontano.)
Quindi il tuo script principale sta ottenendo un SIGTERMprima di poter eseguire il waite echo DONE.
Inserisci
trap 'echo got SIGTERM' TERM
in alto, subito dopo
trap 'killall' INT
ed eseguirlo di nuovo per dimostrarlo.
Come sottolinea Stephane Chazelas, i tuoi figli in background ( process1, ecc.) Ignoreranno SIGINTper impostazione predefinita.
In ogni caso, penso che l'invio SIGTERMavrebbe più senso.
Infine, non sono sicuro che kill -process groupsia garantito per prima cosa andare dai bambini. Ignorare i segnali durante lo spegnimento potrebbe essere una buona idea.
Quindi prova questo:
#!/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