Twoje kill
polecenie 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 -INT
jako opcję i wysyła SIGINT
na 0
( 0
to 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 SIGTERM
domyś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ć SIGTERM
do -INT
, co spowodowałoby błąd składniowy, ale wysyła SIGTERM
do 0
pierwszego i nigdy nie dociera tak daleko).
Więc twój główny skrypt dostaje, SIGTERM
zanim będzie mógł uruchomić wait
i 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 ( process1
itp.) SIGINT
Domyślnie będą ignorować .
W każdym razie myślę, że wysyłanie SIGTERM
byłoby bardziej sensowne.
Wreszcie nie jestem pewien, czy kill -process group
gwarantuje 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