Bash 4.3 added -n
to the wait
builtin, and -p
was added in version 5.1.
From https://www.gnu.org/software/bash/manual/html_node/Job-Control-Builtins.html
wait -n
If the -n option is supplied, wait waits for a single job from the list of pids or jobspecs or, if no arguments are supplied, any job, to complete and returns its exit status. [...]
wait -p
If the -p option is supplied, the process or job identifier of the job for which the exit status is returned is assigned to the variable varname named by the option argument. [...]
The combination of the two options means Bash 5.1+ is actually quite decent at basic multiprocessing. The main drawback now is really just tracking/managing stdout/stderr.
_job1 () { sleep "$( shuf -i 1-3 -n 1 )"s ; true ; }
_job2 () { sleep "$( shuf -i 1-3 -n 1 )"s ; return 42 ; }
limit="2"
i="0"
set -- _job1 _job2
while [ "$#" -gt "0" ] ;do
until [ "$i" -eq "$limit" ] ;do
printf 'starting %s\n' "$1"
"$1" &
pids[$!]="$1"
i="$(( i + 1 ))"
shift
done
if wait -n -p ended_pid ;then
return_code="$?"
printf '%s succeeded, returning "%s"\n' "${pids[ended_pid]}" "$return_code"
else
return_code="$?"
printf '%s FAILED, returning "%s"\n' "${pids[ended_pid]}" "$return_code"
fi
unset 'pids[ended_pid]'
i="$(( i - 1 ))"
done
while [ "${#pids[@]}" -gt "0" ] ;do
if wait -n -p ended_pid ;then
printf '%s succeeded, returning "%s"\n' "${pids[ended_pid]}" "$?"
else
printf '%s FAILED, returning "%s"\n' "${pids[ended_pid]}" "$?"
fi
unset 'pids[ended_pid]'
done
More information (though not on wait -p
): http://mywiki.wooledge.org/ProcessManagement