Как передать псевдофайл дочерней программе?

Запустить новую группу процессов для кода Python (с помощью утилиты setsid ) и любых других процессов (включая собственно приложение). запускается, поэтому при необходимости вы можете убить всю группу процессов.

Для этого вы можете использовать следующую конструкцию:

exec 3>&1
pgid=$(exec setsid bash -c 'echo $$; exec >&3-; exec COMMAND...')

где КОМАНДА ... - это команда и ее параметры, которые вы обычно запускаете. Обратите внимание, что он заключен в одинарные кавычки и что запускаемая команда должна оцениваться как строка (в отличие от обычного выражения оболочки).

Первое перенаправление, 3> & 1 , копирует дескриптор стандартного вывода в дескриптор 3. Перенаправление > & 3- перемещает дескриптор 3 в стандартный вывод.

$ (...) выполняет ... и оценивает данные, которые он записал на стандартный вывод.Выше мы считываем стандартный вывод в переменную оболочки pgid .

Подоболочка ( ... ) заменяется утилитой setsid , которая выполняет свой аргумент в новом сеансе (группе процессов). Здесь он выполняет bash , который распечатывает PID текущего процесса ( $$ ), перемещает исходный стандартный вывод из дескриптора 3 назад и заменяет себя / выполняет желаемый КОМАНДА ... .

Оболочка будет выполнять эту строку, пока выполняется КОМАНДА ... , и перейдет к следующей строке только после выхода самой КОМАНДА ... .

Если КОМАНДА ... оставляет запущенными ложные процессы, и вы хотите их убить, все, что вам нужно сделать, это запустить

kill -SIGNAL -$pgid

Вопрос в том, какой сигнал отправить. KILL немедленно уничтожит оставшиеся процессы в группе процессов, поэтому это самый простой вариант. Однако, если процессы ведут себя нормально, вы можете попросить их выйти, послав вместо этого сигнал TERM . Конечно, иногда процессы могут оставаться в нестабильном состоянии, чтобы они не реагировали на TERM и их нужно было KILL ed. Чтобы решить эту проблему, вы можете использовать небольшой цикл и ps , чтобы увидеть, остались ли какие-либо процессы:

retries=50
while ((1)); do

    # Processes left?
    left=$(ps -o pid= -s $pgrp)
    [ -n "$left" ] || break

    # Ask them to terminate.
    kill -TERM $left

    # Wait 0.1 seconds.
    sleep .1

    # Decrement the retry counter.
    ((--retries > 0)) || break
done

# If there are any processes left in the group,
# send them a KILL signal.
left=$(ps -o pid= -s $pgrp)
[ -n "$left" ] && kill -KILL $left

Обратите внимание, что 50 повторных попыток (по 0,1 секунды каждая) означают, что это ждет только до 5 секунд. перед отправкой сигнала уничтожения. Это может быть неподходящим значением в зависимости от приложения и типа оборудования, на котором оно работает.Например, если машина представляет собой портативный компьютер, и приложение сохраняет некоторую историю или регистрируется в нескольких файлах, а диск оказывается в спящем режиме в точке выхода, я бы увеличил задержку, возможно, до 15–30 секунд.

2
16.11.2017, 18:59
0 ответов

Теги

Похожие вопросы