On 7/13/25 12:37 PM, John Sidles wrote:

Bash Version: 5.3
Patch Level: 0
Release Status: release

Description:
MacOS Homebrew bash '5.3.0(1)-release' (apparently?) breaks 'wait'

bash-settings are as follows (in my experiments,
the sole critical setting is "posix on")



Repeat-By:
# SUMMARY: the following three commands
#   minimally elicit a failure-to-wait bug
set -o posix ;
mapfile -t JOBS < <(jobs -rp);
sleep 10 & wait -f -n $! ;
# FAILURE: 'wait' DOES NOT WAIT

It does wait, and returns a status, it just isn't waiting for the process
you think it is.

This was the result of a *long* (months-long) 2024 discussion in bug-bash.
Here are some threads from each month that capture the discussion:

https://lists.gnu.org/archive/html/bug-bash/2024-06/msg00213.html
https://lists.gnu.org/archive/html/bug-bash/2024-07/msg00013.html
https://lists.gnu.org/archive/html/bug-bash/2024-08/msg00054.html
https://lists.gnu.org/archive/html/bug-bash/2024-09/msg00007.html
https://lists.gnu.org/archive/html/bug-bash/2024-10/msg00068.html

The short story is that `wait -n' now returns the status of any process
that's completed and hasn't been waited for yet, just like `wait'. It's
not restricted to processes that terminates after it's invoked. It does
this even when it's given a list of pid or job arguments, which is
where the problem here arises. That's probably not what I intended with
the change in the first place, but it was a fast-moving target.

The fix for your case is to insert `wait' without arguments after the
call to mapfile aned before the sleep. That way you ensure that the
`wait -n' waits for the sleep process. In fact, your script above
doesn't need `wait -n' at all; it can use `wait'.

If you'd like to play around with the source code, here's a patch that
restores the bash-5.2 behavior for `wait -n' with pid arguments.

Chet

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    c...@case.edu    http://tiswww.cwru.edu/~chet/
*** ../bash-5.3/jobs.c  Fri Mar  7 18:48:44 2025
--- jobs.c      Mon Jul 14 10:25:13 2025
***************
*** 3539,3543 ****
       one in bgpids. We can do this in posix mode because we'll remove any
       one we find from the table, preserving existing semantics. */
!   if (posixly_correct && (t = bgp_findone ()))
      {
        pid = t->pid;
--- 3539,3543 ----
       one in bgpids. We can do this in posix mode because we'll remove any
       one we find from the table, preserving existing semantics. */
!   if (posixly_correct && (flags & JWAIT_WAITING) == 0 && (t = bgp_findone ()))
      {
        pid = t->pid;

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to