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