How to wait in a bash script for several subprocesses spawned from that script to finish and return exit code !=0 when any of the subprocesses ends with code !=0 ?
Simple script:
#!/bin/bash
for i in `seq 0 9`; do
doCalculations $i &
done
wait
The above script will wait for all 10 spawned subprocesses, but it will always give exit status 0 (see help wait
). How can I modify this script so it will discover exit statuses of spawned subprocesses and return exit code 1 when any of subprocesses ends with code !=0?
Is there any better solution for that than collecting PIDs of the subprocesses, wait for them in order and sum exit statuses?
I've just been modifying a script to background and parallelise a process.
I did some experimenting (on Solaris with both bash and ksh) and discovered that 'wait' outputs the exit status if it's not zero , or a list of jobs that return non-zero exit when no PID argument is provided. E.g.
Bash:
Ksh:
This output is written to stderr, so a simple solution to the OPs example could be:
While this:
will also return a count but without the tmp file. This might also be used this way, for example:
But this isn't very much more useful than the tmp file IMO. I couldn't find a useful way to avoid the tmp file whilst also avoiding running the "wait" in a subshell, which wont work at all.
Here's what I've come up with so far. I would like to see how to interrupt the sleep command if a child terminates, so that one would not have to tune
WAITALL_DELAY
to one's usage.I needed this, but the target process wasn't a child of current shell, in which case
wait $PID
doesn't work. I did find the following alternative instead:That relies on the presence of procfs, which may not be available (Mac doesn't provide it for example). So for portability, you could use this instead:
trap is your friend. You can trap on ERR in a lot of systems. You can trap EXIT, or on DEBUG to perform a piece of code after every command.
This in addition to all the standard signals.
To parallelize this...
Translate it to this...
--max-procs
based on how much parallelism you want (0
means "all at once").xargs
-- but it isn't always installed by default.for
loop isn't strictly necessary in this example sinceecho $i
is basically just regenerating the output of$(whatever_list
). I just think the use of thefor
keyword makes it a little easier to see what is going on.Here's a simplified working example...
There are already a lot of answers here, but I am surprised no one seems to have suggested using arrays... So here's what I did - this might be useful to some in the future.