Alexander Mills
Alexander Mills

Reputation: 99960

Proper way to retrieve return value of wait <pid> command

I have the following code in a bash script:

 for job in `jobs -p`; do
     echo "PID => ${job}"
     if ! wait ${job} ; then
     echo "At least one test failed with exit code => $?" ;
     EXIT_CODE=1;
     fi
 done

wait <pid>, in this case, wait ${job}, should return the exit code, but I don't know how to get/see the value. What I need to do is change the above script to something like this:

for job in `jobs -p`; do
     echo "PID => ${job}"
     CODE=0;
     wait ${job} || CODE=$?
     if ! ${CODE} ; then
     echo "At least one test failed with exit code => ${CODE}" ;
     EXIT_CODE=1;
     fi
 done

is there a cleaner less verbose way to do this? I am confused about how to retrieve the "return value" from wait <pid>, besides using the technique I just used. Is there another way to do it?

Upvotes: 0

Views: 894

Answers (3)

codeforester
codeforester

Reputation: 42999

How about this:

declare -A failures
for job in `jobs -p`; do
  wait "$job" || ((failures[$job] = $?))
done

if (( "${#failures[@]}" > 0 )); then
  # traverse the hash and print which processes failed, along with exit code
fi

Upvotes: 2

Grisha Levit
Grisha Levit

Reputation: 8617

If you really want to be more concise, you could do like:

wait $job || {
   echo "$job failed with code $?"
   EXIT_CODE=1
}

Side Note: for job in $(jobs -p); do might not be the best idea. The jobs list is expanded when the loop starts, but jobs might complete while the loop is running (e.g. while you are waiting for the first job in the list, the second job finishes).

Instead, you could do something like:

while :; do
   wait -n && continue            # wait for any job to finish
   code=$?
   ((code==127)) && break         # no jobs found to wait for
   echo "A test failed with code $code"
done

Upvotes: 2

Joel Cornett
Joel Cornett

Reputation: 24788

Cleaner? What could be cleaner than the most obvious and straightforward way:

wait $job
status=$?
if (( $status != 0 )); then
    ...
fi

Sure it's a tiny bit verbose, but it's also easy to understand. What you don't want is code that will make you scratch your head and be confused.

Upvotes: 1

Related Questions