Как убить всех потомков текущей оболочки при прерывании? - PullRequest
9 голосов
/ 08 июня 2011

Мои сценарии cdist-deploy-to и cdist-mass-deploy (из cdist управление конфигурацией) выполняются в интерактивном режиме (то есть вызываются пользователем).

Эти сценарии вызывают многосценариев, которые снова вызывают некоторые сценарии:

cdist-mass-deploy ...
   cdist-deploy-to ...
       cdist-explorer-run-global ...
           cdist-dir ....

Я хочу выйти / уничтожить все сценарии, как только cdist-mass-deploy будет остановлен элементом управления C (SIGINT) или уничтожен с помощью SIGTERM.

cdist-deploy-to также может быть вызван интерактивно и должен демонстрировать то же поведение.

Использование вариантов ps -ef ... и co для обнаружения всех процессов с ppid выглядит такэто может быть довольно непереносимо.Используя $!не работает, так как на более глубоких уровнях у детей нет фоновых процессов.

Я попытался использовать следующий код:

__cdist_kill_on_interrupt()
{
   __cdist_tmp_removal
   kill 0
   exit 1
}

trap __cdist_kill_on_interrupt INT TERM

Но это приводит к уродливым завершенным сообщениям, а также к segfaultв оболочках (dash, bash, zsh) и, кажется, все равно не останавливает все сразу:

# cdist-mass-deploy -p ikq04.ethz.ch ikq05.ethz.ch
core: Waiting for cdist-deploy-to jobs to finish
^CTerminated
Terminated
Terminated
Terminated
Segmentation fault

Таким образом, вопрос заключается в том, как правильно выйти, включая всех (под) детей, переносимым способом (bourne)shell, поддержка csh не требуется)?

1 Ответ

1 голос
/ 17 июня 2011

Вам не нужно обрабатывать ^ C, это приведет к отправке сигнала всей группе процессов, который уничтожит все процессы, которые не находятся в фоновом режиме.Таким образом, вам не нужно перехватывать INT.

Единственная причина, по которой вы получаете терминатора, когда убиваете его, заключается в том, что kill посылает TERM по умолчанию, но это разумно, если вы сначала обрабатываете TERM.Вы можете использовать kill -INT 0, если хотите избежать сообщений.

(отвечая дополнительной информацией)

Если дочерние процессы выполняются в фоновом режиме, вы можете просто получить их идентификаторы процессов.после их запуска используйте $!специальная переменная оболочки.Соберите их вместе в переменную и просто убейте их все, когда вам нужно завершить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...