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