2012-01-14 1 views
3

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

#!/bin/bash 
gnome-screensaver-command -i -n aeolus-wrapper.sh & 
aeolus & 
qjackctl 

После запуска их, мне нужно следить за Эол и qjackctl и убить оставшиеся два процессов, если выходы aeolus или qjackctl:

# if aeolus exits, kill gnome-screensaver-command and qjackctl 
# if qjackctl exits, kill gnome-screensaver-command and aeolus 

Здесь я застрял. Я был заинтригован this example, который показывает, как использовать цикл until, чтобы отслеживать процесс и перезапускать его, если он умирает, но я не совсем уверен, как добраться оттуда туда, куда я хочу идти. Любые предложения очень приветствуются.

ответ

2

Не используйте время цикла. Просто заблокируйте и дождитесь, пока SIGCHLD сообщит вам, что один из процессов завершен. В ловушке убейте оставшиеся запущенные процессы. Например:

 
#!/bin/bash 

set -m 
trap 'list=$(jobs -rp); test -n "$list" && kill $list' CHLD 
cmd1 & 
cmd2 & 
cmd3 & 
wait 

Выполнение 3 команд. Когда один из них выйдет, остальные два будут отправлены SIGTERM.

+0

Спасибо. Это похоже на то, что я хочу, кроме одного: если я закрываю qjackctl, он убивает команду aeolus и gnome-screensaver. Но если я закрываю aeolus, он не убивает qjackctl. Вместо этого в командной строке я вижу «главный сигнал поймания 12», и скрипт-оболочка продолжает ждать. (Обратите внимание, что qjackctl является интерфейсом GUI для jackd, когда вы начинаете aeolus, он автоматически запускает jackd.) – user1148928

+0

Похоже, aeolus ловит SIGTERM и отправляет SIGSYS на jackd. Вам нужно выяснить, какой сигнал вы можете отправить в aeolus, чтобы успешно его прекратить. –

+0

Оказалось, что: (1) qjackctl на самом деле qjackctl.bin и должен быть указан как таковой; (2) jackd должен быть включен явно в список. Так вот что работает: '#!/Bin/bash set -m trap 'list = $ (jobs -rp); test -n "$ list" && kill $ list 'CHLD gnome-screensaver-command -i -n aeolus-wrapper.sh & jackd -T -ndefault -dalsa -dhw: 0 -r44100 -p1024 -n2 & aeolus & qjackctl.bin & wait' С подходящими разрывами строки, конечно, которые здесь не показаны. Большое спасибо, опять же за помощь. – user1148928

1
if [ "a$(pgrep aeolus)" != "a" ] ; 
then 
    pkill gnome-screensaver-command 
    pkill qjackctl 
fi 

же для qjackctl

Другой синтаксис,

if pgrep aeolus 
then 
    pkill gnome-screensaver-command 
    pkill qjackctl 
fi 
+0

'kill' принимает значение PID – SiegeX

+0

Также' if! pgrep aeolus'; затем ... ' – SiegeX

+0

@SiegeX Сначала я использовал синтаксис' if! '. Это не сработало на моем компьютере для некоторых упражнений. Поэтому я редактировал. 'kill' также теперь заменяется на' pkill'. На самом деле я сохранил эти строки kill для OP для редактирования. –