Убить процесс на левой стороне трубы - PullRequest
0 голосов
/ 27 августа 2018

У меня в bash следующее:

фу | бар

Я хочу, чтобы foo умер, когда сценарий завершен (с использованием сигнала TERM). К сожалению, никто из них не умирает. Я попробовал это:

exec foo | bar

Это абсолютно ничего не достигло. Тогда я попробовал это:

function run() {
    "$@" &
    pid=$!
    trap "kill $pid" EXIT
    wait
}

run foo | bar

Опять ничего. Теперь у меня есть еще один процесс, и ни один из них не умирает, когда я прекращаю работу родителя.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Убив всю группу процессов вместо bash (родитель), вы также можете отправить сигнал уничтожения всем дочерним элементам. Примеры синтаксиса:

kill -SIGTERM -$!
kill -- -$!

Пример:

bash -c 'sleep 50 | sleep 40' & sleep 1; kill -SIGTERM -$!; wait; ps -ef | grep -c sleep
[1] 14683
[1]+  Terminated              bash -c 'sleep 50 | sleep 40'
1

Обратите внимание, что wait здесь ожидает эффективного уничтожения bash, что занимает несколько миллисекунд. Также обратите внимание, что конечным результатом (1) является сам «grep sleep». Результат 3 покажет, что это не работает, так как все еще будут работать два дополнительных спящих процесса.

Руководство kill упоминает:

-n
where n is larger than 1. All processes in process group n are signaled.
When an argument of the form '-n' is given, and it is meant to denote a
process group, either the signal must be specified first, or the argument
must be preceded by a '--' option, otherwise it will be taken as the signal
to send.
0 голосов
/ 27 августа 2018

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

trap 'kill $foo_pid; rm -f foo_out' EXIT

mkfifo foo_out
foo > foo_out & foo_pid=$!
bar < foo_out
...