Skip to content

Instantly share code, notes, and snippets.

@jzawodn
Created November 21, 2008 15:13
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jzawodn/27452 to your computer and use it in GitHub Desktop.
Save jzawodn/27452 to your computer and use it in GitHub Desktop.
how to wait on multiple background processes and check exit status in bash
#!/bin/bash
FAIL=0
echo "starting"
./sleeper 2 0 &
./sleeper 2 1 &
./sleeper 3 0 &
./sleeper 2 0 &
for job in `jobs -p`
do
echo $job
wait $job || let "FAIL+=1"
done
echo $FAIL
if [ "$FAIL" == "0" ];
then
echo "YAY!"
else
echo "FAIL! ($FAIL)"
fi
@abhiomkar
Copy link

that's a nice workaround.. but, using just the wait command (without passing the process ID) would have worked too? So that, it waits for all the background process to get complete.

./sleeper 2 0 &
./sleeper 2 1 &
./sleeper 3 0 &
./sleeper 2 0 &

wait

Please let me know your thoughts.

(I got here from your blog post - http://jeremy.zawodny.com/blog/archives/010717.html)

@moebiuseye
Copy link

The idea is to know how many processes failed. You can't do that without the for loop.

@ORESoftware
Copy link

you can also use trap, something like this:

#!/usr/bin/env bash

set -m # allow for job control
EXIT_CODE=0;  # exit code of overall script

function foo() {
   echo "CHLD exit code is $1"
      echo "CHLD pid is $2"
      echo $(jobs -n)

   if [[ $? > 0 ]]; then
      echo "at least one test failed";
      EXIT_CODE=1;
   fi
}

trap 'foo $? $$' CHLD

DIRN=$(dirname "$0");

commands=(
    "{ echo "foo" && exit 4; }"
    "{ echo "bar" && exit 3; }"
    "{ echo "baz" && exit 5; }"
)

clen=`expr "${#commands[@]}" - 1` # get length of commands - 1

for i in `seq 0 "$clen"`; do
    (echo "${commands[$i]}" | bash) &   # run the command via bash in subshell
    echo "$i ith command has been issued as a background job"
done

# wait for all to finish
wait;

echo "EXIT_CODE => $EXIT_CODE"
exit "$EXIT_CODE"

# end

@lyscorpio
Copy link

but how could you know the first subprocess in loop is the one finished first, if the later ones in loop finished early, what is the return code

@iridiumcao
Copy link

that's a nice workaround.. but, using just the wait command (without passing the process ID) would have worked too? So that, it waits for all the background process to get complete.

./sleeper 2 0 &
./sleeper 2 1 &
./sleeper 3 0 &
./sleeper 2 0 &

wait

Please let me know your thoughts.

(I got here from your blog post - http://jeremy.zawodny.com/blog/archives/010717.html)

So nice, thank you! It works in my script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment