Ваш 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