According to the Bash 4.4 changelog:
https://lists.gnu.org/archive/html/info-gnu/2016-09/msg00008.html
There are a few incompatible changes between bash-4.3 and bash-4.4.
Bash now retains the exit status only of asynchronous jobs, as opposed
to all jobs. This means that it is not possible to use `wait' to
retrieve the status of a previously-completed synchronous command.
https://fossies.org/diffs/bash/4.3.46_vs_4.4/CHANGES-diff.html
Bash only adds asynchronous commands to the table of background pids
whose status it remembers, to avoid it growing too large during
scripts that create and reap large numbers of child processes. This
means that `wait' no longer works on synchronous jobs, but $? can be
used to get the exit status in those cases.
I've already been bitten by some other breaking changes between 4.3 and 4.4 but I don't know how to write an example which tests this particular change.
What is the difference between a synchronous job versus an asynchronous one in Bash and where did it store a table of pids to be queried by wait?
Best Answer
Example:
4.3
4.4
You can no longer use
wait
to get the exit status of that subshell that run in foreground (synchronously). foreground refers to jobs of interactive shells, but the same applies for commands run in non-interactive shells.Note that it also applies to background jobs that are later put in foreground with
fg
:With
bash-4.3
and beforebash
would remember the exit status of every past background and foreground command. That would not be useful for foreground commands as usually, you don't know their pid in the script and also in things like:cmd1
's pid could very well have been reused forcmd2
. In that casewait "$!"
would get you the exit status ofcmd2
instead ofcmd1
. Recording the pid of only asynchronous commands slightly reduces the risk ofwait
giving you the exit status of the wrong command (beside the performance issue mentioned by @Christopher).