for RUN in $(seq 1 $RUNS); do
foo &
if (( (RUN % 10) == 0 )); then
wait
fi
done
or, with an alternative loop construct (IMHO nicer looking):
for (( r = 1; r <= RUNS; ++i )); do
foo &
if (( (r % 10) == 0 )); then
wait
fi
done
You may additionally want a lone wait after the loop if $RUNS is not a multiple of 10.
Instead of having RUNS as the total number of runs to do, one could also imagine having n batches of 10 jobs:
for (( i = 0; i < n; ++i )); do
printf 'starting batch %d...\n' "$i"
for (( j = 0; j < 10; ++j )); do
foo &
done
echo 'waiting...'
wait
done
Alternative solution using xargs and no explicit wait:
seq 1 "$RUNS" | xargs -n 1 -P 10 foo
This would however give the foo process a command line argument (one of the integers produced by seq) which may not be wanted. This gets rid of that issue:
seq 1 "$RUNS" | xargs -n 1 -P 10 sh -c 'foo'