Twoje killpolecenie jest cofnięte.
Podobnie jak wiele poleceń UNIX, opcje zaczynające się od minus muszą być na pierwszym miejscu, przed innymi argumentami.
Jeśli napiszesz
kill -INT 0
widzi to -INTjako opcję i wysyła SIGINTna 0( 0to specjalny numer oznaczający wszystkie procesy w bieżącej grupie procesów).
Ale jeśli napiszesz
kill 0 -INT
widzi 0, decyduje, że nie ma więcej opcji, więc używa SIGTERMdomyślnie. I wysyła to do bieżącej grupy procesów, tak samo jak gdybyś to zrobił
kill -TERM 0 -INT
(próbowałby również wysłać SIGTERMdo -INT, co spowodowałoby błąd składniowy, ale wysyła SIGTERMdo 0pierwszego i nigdy nie dociera tak daleko).
Więc twój główny skrypt dostaje, SIGTERMzanim będzie mógł uruchomić waiti echo DONE.
Dodaj
trap 'echo got SIGTERM' TERM
u góry, zaraz po
trap 'killall' INT
i uruchom go ponownie, aby to udowodnić.
Jak wskazuje Stephane Chazelas, dzieci w tle ( process1itp.) SIGINTDomyślnie będą ignorować .
W każdym razie myślę, że wysyłanie SIGTERMbyłoby bardziej sensowne.
Wreszcie nie jestem pewien, czy kill -process groupgwarantuje się, że najpierw pójdzie do dzieci. Ignorowanie sygnałów podczas wyłączania może być dobrym pomysłem.
Spróbuj tego:
#!/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