NOTE. As stated in mobrule, my original answer will not work, because a wait configured without arguments expects all children to complete. Therefore, the following "parallelexec" script, which avoids polling due to more child processes:
#!/bin/bash N="$1" I=0 { if [[ "$#" -le 1 ]]; then cat else while [[ "$#" -gt 1 ]]; do echo "$2" set -- "$1" "${@:3}" done fi } | { d=$(mktemp -d /tmp/fifo.XXXXXXXX) mkfifo "$d"/fifo exec 3<>"$d"/fifo rm -rf "$d" while [[ "$I" -lt "$N" ]] && read C; do ($C; echo >&3) & let I++ done while read C; do read -u 3 ($C; echo >&3) & done }
The first argument is the number of parallel jobs. If there are more of them, each of them is launched as a task, otherwise all the commands to start are read from stdin line by line.
I use a named pipe (which goes into oblivion as soon as the shell opens it) as a synchronization method. Since only single bytes are recorded, problems with race conditions cannot complicate.
source share