In 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
Result:
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
Result is:
3 is 1
3 is 2
3 is 3
and I am quite baffled for the following reasons:
- The only process
wait
should be waiting to finish is assigning the variable, then the next step in the script should be run (echo
).a=3
should only happen in the last iteration of the loop. - As far as I know,
for
-loops are run in subshells andwait
has a scope only for the shell it was launched in. So it should not even be waiting for thefor
-loop to finish (as this is the parent). - At no point have I specified the
echo
to 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.
Unsetting 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.
a
first (withunset a
). You can't assign a variable in a background task and then expect it to be set in the parent shell.