Bash – How to run multiple processes and exit if any of them exits or fails

bashconcurrencyexit-statusshell

I am running multiple processes and want to exit with the appropriate exit code (this means error on failure, success otherwise) if any of them fails or exists.

Additionally if any child process exits or fails, any other child processes should also be shut down.

My current non-functional solution (yarn is just an example; may be any other command):

#!/bin/bash -e

# Run other process before start
sh ./bin/optimize.sh

trap 'exit' INT TERM
trap 'kill -INT 0' EXIT

# Run Schedule
sh ./bin/schedule.sh &
# Run a long running task
yarn task &

wait

./bin/schedule.sh:

#!/bin/bash -e

while true; do
  yarn schedule
  sleep 30
done

If something in yarn schedule fails, everything exists correctly. But when I kill the process via ctrl+c or yarn task exits yarn schedule keeps running.

How to get this working regardless of what the child processes are (bash, yarn, php or whatever)?

I can't use GNU parallel.

Best Answer

GNU Parallel has --halt. It will kill all running jobs if one of the jobs finishes or dies and will return false if the job failed:

parallel --halt now,done=1 ::: 'sleep 1;echo a' 'sleep 2;echo b' ||
  echo the job that finished failed

parallel --halt now,done=1 ::: 'sleep 1;echo a;false' 'sleep 2;echo b' ||
  echo the job that finished failed

For systems that do not have GNU Parallel installed, you can typically write your script on a system that has GNU Parallel, and use --embed to embed GNU Parallel directly into the script:

parallel --embed > myscript.sh
Related Question