Как запустить два процесса, как если бы они были одним в Bash? - PullRequest
4 голосов
/ 02 апреля 2009

У меня есть две команды foo и bar.

foo работает долго без активности stdin или stdout / stderr. bar является клиентом foo и работает с stdout / stderr, но без активности stdin.

Я бы хотел запустить их из одной оболочки, чтобы иметь возможность убивать их с помощью ctrl-c и видеть вывод из bar по мере его появления.

т.е. что-то вроде этой последовательности

foo & бар убить -9

но без необходимости вручную убивать - вместо этого это просто происходит по Ctrl-C

Есть ли способ написать это?

спасибо

Ответы [ 2 ]

5 голосов
/ 02 апреля 2009

Не используйте kill -9.

Вы хотите поймать в ловушку EXIT, а не INT.

trap 'kill $fooPid $barPid' EXIT
foo & fooPid=$!
bar & barPid=$!
wait

Это решение всегда гарантирует завершение foo и bar, независимо от причины выхода (исключая SIGKILL 'ed).

Если вы хотите избежать сохранения PID (что связано с некоторыми условиями гонки), вы можете сделать это вместо этого:

trap 'kill $(jobs -p)' EXIT
foo &
bar &
wait

Это лучшее (и более чистое) решение, если у вашего сценария нет других заданий.

Ps : Эти решения означают, что foo и bar могут писать в ваш терминал (ваш скрипт stdout), но ни один не может читать из stdin. Если вам нужно foo или bar для чтения со стандартного ввода, решение становится на бит более сложным.

2 голосов
/ 02 апреля 2009

Вы можете настроить bash-скрипт для запуска программ и использовать trap для захвата CTRL-C. Затем в функции, вызываемой trap, просто убейте программы.

Прошло много времени с тех пор, как я это сделал, но я думаю, что это иллюстрирует следующее.

#!/bin/bash
xx() {
    kill -9 $pid1
    kill -9 $pid2
    echo bye
}
trap 'xx' SIGINT
sleep 1000 &
pid1=$!
sleep 2000 &
pid2=$!
sleep 3600

Просто запустите этот скрипт и нажмите CTRL-C, и вы обнаружите, что он убивает два спящих процесса.

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