The code spawns a number of background tasks in a loop. Each of these tasks run commands related to
The jobs may be spawned very fast and to not overwhelm the system, the code only runs 20 of them before waiting for all the currently running backgrund tasks to finish. It is the call to
wait that makes the script wait for all background tasks to finish before continuing, spawning another 20 jobs.
The arithmetic test that precedes the call to
wait will be true for each value of
$i evenly divisible by 20, i.e. for
$i = 20,
$i = 40, etc.
The syntax used for the arithmetic expansions,
$[ ... ], is obsolete
bash syntax that nowadays would have been written
$(( ... )) (which is portable). The
% operator is the ordinary modulus operator.
Apart from the use of the obsolete syntax, the shell also has a possible issue with quoting. It's the variable expansions
$M, and also
$i, that lack quoting, as does the two command substitutions. If any of these contain or generate characters present in
$IFS (space, tab, newline, by default), you may expect the script to fail or at least to misbehave.
The code also lacks a final
wait after the loop, to properly wait for any of the last few jobs started by the loop. This would not be needed if it can be guaranteed that the loop will always run
n*20 times (for some whole number