Ваша killкоманда назад.
Як і багато команд UNIX, параметри, які починаються з мінусу, повинні бути першими, перш ніж інші аргументи.
Якщо ви пишете
kill -INT 0
він розглядає -INTяк варіант і надсилає SIGINTдо 0( 0це спеціальне число, яке означає всі процеси в поточній групі процесів).
Але якщо ти пишеш
kill 0 -INT
він бачить 0, вирішує, що немає більше варіантів, тому використовує SIGTERMза замовчуванням. І посилає це поточній групі процесів так само, як і ви
kill -TERM 0 -INT
(Було б також спробувати відправити SIGTERMна -INT, що викличе синтаксичну помилку, але він посилає SIGTERMдо 0першого, і ніколи не отримує , що далеко.)
Отже, ваш основний сценарій - це отримання, SIGTERMперш ніж він запускає waitта echo DONE.
Додайте
trap 'echo got SIGTERM' TERM
вгорі, відразу після
trap 'killall' INT
і запустіть його ще раз, щоб довести це.
Як зазначає Стефан Шазелас, ваші діти ( process1тощо) SIGINTза замовчуванням ігнорують .
У будь-якому випадку, я думаю, що надсилання SIGTERMматиме більше сенсу.
Нарешті, я не впевнений, чи kill -process groupгарантовано спочатку піти до дітей. Ігнорування сигналів під час вимкнення може бути хорошою ідеєю.
Тому спробуйте це:
#!/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