linux - сигнал не передан мультикоманде - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь понять, почему сигналы не передаются должным образом при этой настройке. Простой тест, у меня есть скрипт на python, который регистрирует обработчик sigterm и печатает, если он его получает. Я подтвердил, что это работает, если я запускаю его и отправляю СРОК.

Тем не менее, я использую этот подпроцесс python с useShell = True. useShell запускает команду с / bin / sh -c ...

Если я это сделаю, то на самом деле это тоже работает:

$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
$ kill 6207
 signum 15

Однако у меня есть сценарии, которые выполняют цепочечные команды, т.е. /foo/bar.sh; some_other_script.py. В этом случае сигнал не передается в окончательный сценарий:

$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
$ kill 8015

То же самое происходит, если я пытаюсь использовать && вместо; Я пытаюсь понять, что здесь происходит, и есть ли способ получить сигнал для прохождения. Побочный момент: Основная причина, по которой скрипт запускает многоцепочечные команды, заключается в том, что первая команда устанавливает некоторую среду для использования второй.

signal_test.py:

import time
import signal
import sys

def handler( signum, frame ):
    print( "signum %d\n" % signum ) 
    sys.exit(signum)

signal.signal( signal.SIGTERM, handler )
time.sleep(60)

1 Ответ

0 голосов
/ 12 ноября 2018

Позвольте мне объяснить детали.

Возвращенный номер bash не pid, это pgid (идентификатор группы процессов)

Когда вы запускаете команду в оболочке, оболочка создаст новую группу процессов. Группа будет содержать весь процесс в команде. И pgid - это то же самое, что pid для лидера процесса.

Группа процессов означает задачу в слове многозадачность, оболочка может переключаться между группами, используя bg (^ Z) / fg. Весь сигнал (например, ^ C), сгенерированный оболочкой (на самом деле pty, другая история), будет отправлен всей группе вместо процесса лидера.

Когда shell создает несколько процессов или один процесс?

Ответ очевиден: оболочка создаст несколько процессов, когда команды не могут быть обработаны одним процессом.

В первом примере

$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207

выдается одна команда, поэтому сама вложенная оболочка (/bin/sh) становится python. Примечания: даже если есть только один процесс, новая группа процессов будет содержать единственный процесс.

Во втором примере

$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015

введены две команды, задача не может быть выполнена одним процессом, поэтому требуется несколько процессов:

/bin/sh
    echo
    python

Создана группа процессов, содержащая эти три процесса.

Как отправлять сигналы группе процессов?

Используйте

kill <SIGNAL> -<pgid>

Знак минус перед pgid необходим.

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