man bash it says:
wait [-fn] [id ...]
Wait for each specified child process and return its termination status. Each id may be a process ID or a job specification; if a job spec is given, all processes in that job's pipeline are waited for. If id is not given, all currently active child processes are waited for, and the return status is zero. If the -n option is supplied, wait waits for any job to terminate and returns its exit status.
And typical examples like
command1 & command2 & command3 & wait
will mean the three commands run in parallel and the next step is only done once ALL of them are finished.
My problem lies in the results of these two bash scripts:
#!/bin/bash for i in 1 2 3 ; do a=$i echo "$a is $i" done 2>/dev/null
1 is 1 2 is 2 3 is 3
Pretty much what I expected. Now I assume assigning the variable is a long process, so I wait for it:
#!/bin/bash for i in 1 2 3 ; do a=$i & wait echo "$a is $i" done 2>/dev/null
3 is 1 3 is 2 3 is 3
and I am quite baffled for the following reasons:
- The only process
waitshould be waiting to finish is assigning the variable, then the next step in the script should be run (
a=3should only happen in the last iteration of the loop.
- As far as I know,
for-loops are run in subshells and
waithas a scope only for the shell it was launched in. So it should not even be waiting for the
for-loop to finish (as this is the parent).
- At no point have I specified the
echoto run in parallel to some other process, so I did not expect a racing condition.
So why is the
a-variable set with the last loop iteration when the variable
$i is not? What part of the
wait command did I misunderstand? The behavior is completely off my expectations.
GNU bash, version 5.0.3(1) on a 5.7.0-0.bpo.2-amd64 Linux kernel.
a beforehand makes the second script return this
is 1 is 2 is 3
i.e. the variable is never set and was dragged from my previous run.