Bash – From bash, spawn two processes and exit both if either sibling exits

bashprocess

From bash, I am spawning two processes. These two processes depend on each other. I want both to exit if either one dies. What is the cleanest way to do that? Currently I have the following:

# start process a
/bin/program_a;
a_pid=$!

# start process b
/bin/program_b;
b_pid=$!

# kill process b if process a exits
wait $a_pid
echo "a_pid died, killing process b"
kill -9 $b_pid

But this only helps process b exit if process a dies. How to I also make process a exit if process b dies?

Best Answer

With zsh:

pids=()
trap '
  trap - CHLD
  (($#pids)) && kill $pids 2> /dev/null
' CHLD

sleep 2 & pids+=$!
sleep 1 & pids+=$!
sleep 3 & pids+=$!

wait

(here using sleep as test commands).

With bash it would seem the CHLD trap is only run when the m option is on. You don't want to start your jobs under that option though as that would run them in separate process groups. Also note that resetting the handler within the handler doesn't seem to work with bash. So the bash equivalent would be something like:

pids=()
gotsigchld=false
trap '
  if ! "$gotsigchld"; then
    gotsigchld=true
    ((${#pids[@]})) && kill "${pids[@]}" 2> /dev/null
  fi
' CHLD

sleep 2 & pids+=("$!")
sleep 1 & pids+=("$!")
sleep 3 & pids+=("$!")

set -m
wait
set +m
Related Question