4

I'm trying to write a wrapper script in bash to automate startup and shutdown of three programs I need to run simultaneously:

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

After starting them, I need to monitor aeolus and qjackctl and kill the remaining two processes if either aeolus or qjackctl exits:

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

This is where I'm stuck. I was intrigued by this example that shows how to use an until loop to monitor a process and restart it if it dies, but I'm not quite sure how to get from there to where I want to go. Any suggestions very welcome.

Community
  • 1
  • 1
user1148928
  • 63
  • 1
  • 4

2 Answers2

3

Do not use a while loop. Just block and wait for a SIGCHLD to tell you that one of the processes has terminated. In the trap, kill the remaining running processes. For example:

#!/bin/bash

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

This will run 3 commands. When one exits, the other two will be sent SIGTERM.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Thank you. This looks like what I want, except for one thing: If I close qjackctl, it does kill aeolus and gnome-screensaver-command. But if I close aeolus, it does not successfully kill qjackctl. Instead, on the command line I see "jack main caught signal 12," and the wrapper script continues to wait. (Note that qjackctl is a GUI frontend for jackd; when you start aeolus, it starts jackd automatically.) – user1148928 Jan 14 '12 at 16:54
  • It sounds like aeolus is catching the SIGTERM and sending SIGSYS to jackd. You need to figure out what signal you can send to aeolus to successfully terminate it. – William Pursell Jan 14 '12 at 17:57
  • Turned out to be: (1) qjackctl is actually qjackctl.bin, and needs to be listed as such; (2) jackd needs to be included explicitly in the list. So this is what works: `#!/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` With approriate line breaks, of course, which aren't shown here. Many thanks, again, for the help. – user1148928 Jan 15 '12 at 02:28
1
if [ "a$(pgrep aeolus)" != "a" ] ; 
then 
    pkill gnome-screensaver-command 
    pkill qjackctl
fi

same for qjackctl

Another syntax,

if pgrep aeolus
then 
    pkill gnome-screensaver-command 
    pkill qjackctl
fi
Shiplu Mokaddim
  • 56,364
  • 17
  • 141
  • 187