3

Is it possible in Bash to spawn multiple processes and after the last process finishes, report how many of the processes terminated correctly/didn't core dump?

Or would it be better to do this in Python?

(I'd ideally like to report which command failed, if any)

user997112
  • 29,025
  • 43
  • 182
  • 361
  • Related: [Get exit code of a background process](https://stackoverflow.com/q/1570262/45249), in particular [this answer](https://stackoverflow.com/a/29535256/45249) – mouviciel Sep 26 '19 at 07:32

3 Answers3

0

You can hopefully leverage GNU Parallel and its failure handling. General example:

parallel ::: ./processA ./processB ./processC

Specific example... here I run 3 simple jobs, each surrounded by single quotes and set it up to stop once all jobs are complete or failed:

parallel --halt soon,fail=100% ::: 'echo 0 && exit 0' 'echo 1 && exit 1' 'echo 2 && exit 2'

Output

0
1
parallel: This job failed:
echo 1 && exit 1
2
parallel: This job failed:
echo 2 && exit 2

By default, it will run N jobs in parallel, where N is the number of cores your CPU has, if you just want the jobs to be run sequentially, use:

parallel -j 1 ...

Obviously you could pipe the output through grep -c "This job failed" to count the failures.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
0

Assuming you have a file with the commands:

cmd1
cmd2
cmd3

Then this will give you the number of failed jobs as long as you have at most 100 failures:

cat file | parallel
a=$?; echo $((`wc -l <file`-$a))

To get exactly which jobs failed use --joblog.

cat file | parallel --joblog my.log
# Find non-zero column 7 
grep -v -P '(.*\t){6}0\t.*\t' my.log
Ole Tange
  • 31,768
  • 5
  • 86
  • 104
0

It's easy.

First run your jobs in the background. Remember the pids.

Then for each child execute wait $pid and see the wait exit status, which is equal to the exit status of the childs pid you pass to it.

If the exit status is zero, it means the child terminated successfully.

#!/bin/bash

exit 0 &
childs+=($!)
exit 1 &
childs+=($!)
exit 2 &
childs+=($!)
echo 1 &
childs+=($!)

successes=0

for i in "${childs[@]}"; do
        wait $i
        if (($? == 0)); then
                ((successes++))
        fi
done

# will print that 2 processes (exit 0 and echo 1) terminated successfully
printf "$successes processes terminated correctly and didn't core dump\n"
KamilCuk
  • 120,984
  • 8
  • 59
  • 111