Я пытаюсь настроить сценарий оболочки так, чтобы он запускал фоновые процессы, и когда я Ctrlc сценарий оболочки, он убивает дочерних элементов, а затем завершается.
Лучшее, что мне удалось придумать, это это. Похоже, чтоkill 0 -INT
также убивает сценарий до того, как произойдет ожидание, поэтому сценарий оболочки умирает до завершения дочерних процессов.
Любые идеи о том, как я могу заставить этот сценарий оболочки ждать смерти детей после отправки INT
?
#!/bin/bash
trap 'killall' INT
killall() {
echo "**** Shutting down... ****"
kill 0 -INT
wait # Why doesn't this wait??
echo DONE
}
process1 &
process2 &
process3 &
cat # wait forever
Ответы:
Ваш
kill
команда обратная.Как и во многих командах UNIX, параметры, начинающиеся с минуса, должны предшествовать другим аргументам.
Если ты пишешь
он видит в
-INT
качестве опции, и посылаетSIGINT
к0
(0
это специальный номер означает все процессы в текущей группе процессов).Но если вы напишите
он видит
0
, решает, что больше нет вариантов, поэтому используетSIGTERM
по умолчанию. И отправляет это в текущую группу процессов, так же, как если бы вы сделали(он также попытался бы отправить
SIGTERM
в-INT
, что вызвало бы синтаксическую ошибку, но он отправилSIGTERM
бы0
сначала, и никогда не заходил так далеко.)Таким образом, ваш основной скрипт получает
SIGTERM
до того, как он запуститwait
иecho DONE
.Добавлять
наверху, сразу после
и запустите его снова, чтобы доказать это.
Как указывает Стефан Шазелас, ваши дети (
process1
и т. Д.) Будут игнорироватьSIGINT
По умолчанию по умолчанию.В любом случае, я думаю, что отправка
SIGTERM
будет иметь больше смысла.Наконец, я не уверен,
kill -process group
гарантировано ли будет идти в первую очередь к детям. Игнорирование сигналов при выключении может быть хорошей идеей.Итак, попробуйте это:
источник
К сожалению, команды, запускаемые в фоновом режиме, устанавливаются оболочкой так, что они игнорируют SIGINT, и, что еще хуже, они не могут игнорировать его
trap
. В противном случае все, что вам нужно сделать, этоПотому что process1 и process2 получают SIGINT, когда вы нажимаете Ctrl-C, так как они являются частью одной группы процессов, которая является основной группой процессов терминала.
Приведенный выше код будет работать с pdksh и zsh, которые в этом отношении не соответствуют POSIX.
С другими оболочками вам придется использовать что-то еще для восстановления обработчика по умолчанию для SIGINT, например:
или используйте другой сигнал, такой как SIGTERM.
источник
Для тех, кто просто хочет убить процесс и дождаться его смерти, но не бесконечно :
Максимальное время ожидания 60 секунд для каждого типа сигнала.
Предупреждение. Этот ответ никоим образом не связан с перехватом сигнала уничтожения и его отправкой.
Он выбирает приложение для уничтожения по имени или аргументам. Сохраняйте скобки для первой буквы названия приложения, чтобы избежать совпадения с самим grep.
С некоторыми изменениями вы можете напрямую использовать PID или более простое
pidof process_name
вместоps
оператора.Детали кода: последний шаг - получить PID без пробелов.
источник
Если вам нужно управлять некоторыми фоновыми процессами, почему бы не использовать функции управления заданиями bash?
источник
Так что я тоже возился с этим. В Bash вы можете определять функции и делать с ними причудливые вещи. Я и мои коллеги используем
terminator
, поэтому для пакетного выполнения мы обычно создаем целую кучу окон-терминаторов, если хотим просмотреть вывод (менее элегантный, чемtmux
вкладки, но вы можете использовать более похожий на GUI интерфейс, ха-ха).Вот настройки, которые я придумал, а также пример того, что вы можете запустить:
Запуск это
Edit @Maxim, только что увидел ваше предложение, что делает его намного проще! Благодарность!
источник