Re: `wait` triggers an infinite loop when used in an EXIT trap

Félix Hauri via Bug reports for the GNU Bourne Again SHell <[email protected]>
Newsgroups gmane.comp.shells.bash.bugs
Message-ID <[email protected]>
Things seem a little more subtle:

In order do make some light on this, ther's my version:

    #!/bin/bash
    
    jobs=()
    
    cleanup() {
        echo "PID: $$ CMD: $BASH_COMMAND"
        kill -- "${jobs[@]}"
        wait
    }
    
    trap cleanup EXIT
    
    true & jobs+=($!)
    true & jobs+=($!)
    true & jobs+=($!)
    true & jobs+=($!)
    true & jobs+=($!)
    
    # trap cleanup EXIT
    
    declare -p jobs

Run on Debian Trixie (bash 5.2.15(1)-release), when `trap` is defined
before `true` commands, I often (but not always) see:

    declare -a jobs=([0]="253085" [1]="253086" [2]="253087" [3]="253088" [4]="253089")
    PID: 253084 CMD: declare -p jobs
    trapChilds.sh: line 7: kill: (253085) - No such process
    trapChilds.sh: line 7: kill: (253086) - No such process
    trapChilds.sh: line 7: kill: (253087) - No such process
    PID: 253084 CMD: true
    trapChilds.sh: line 7: kill: (253085) - No such process
    trapChilds.sh: line 7: kill: (253086) - No such process
    trapChilds.sh: line 7: kill: (253087) - No such process

Where `cleanup` was run two times! Seem to be trigger by one of `true`
command's EXIT signal.

( $BASH_COMMAND should contain `declare -p` !)

When run on 5.3.9(1)-release, I see sometime:

    declare -a jobs=([0]="254729" [1]="254730" [2]="254731" [3]="254732" [4]="254733")
    PID: 254727 CMD: declare -p jobs
    trapChilds.sh: line 7: kill: (254729) - No such process
    trapChilds.sh: line 7: kill: (254730) - No such process
    trapChilds.sh: line 7: kill: (254731) - No such process
    trapChilds.sh: line 7: kill: (254732) - No such process
    trapChilds.sh: line 7: kill: (254733) - No such process

But some other time: 

    declare -a jobs=([0]="254707" [1]="254708" [2]="254709" [3]="254710" [4]="254711")
    PID: 254705 CMD: declare -p jobs
    trapChilds.sh: line 7: kill: (254707) - No such process
    trapChilds.sh: line 7: kill: (254710) - No such process
    PID: 254705 CMD: true
    PID: 254705 CMD: true
    trapChilds.sh: line 7: kill: (254707) - No such process
    trapChilds.sh: line 7: kill: (254707) - No such process
    trapChilds.sh: line 7: kill: (254710) - No such process
    trapChilds.sh: line 8: wait: pid 254708 is not a child of this shell
    trapChilds.sh: line 8: wait: pid 254708 is not a child of this shell
    trapChilds.sh: line 8: wait: pid 254708 is not a child of^C

I had to hit Ctrl+C!

Note: If the trap is defined AFTER last `true` was ran, everything work fine.

Le Mon, Jan 05, 2026 at 11:50:24AM -0500, Chet Ramey a écrit :
> On 1/2/26 2:23 PM, Aleksey Covacevice wrote:
> 
> > Bash Version: 5.3
> > Patch Level: 8
> > Release Status: release
> > 
> > Description:
> >      `wait` triggers an infinite "pid is not a child of this shell" loop when
> >      used in an EXIT trap.
> > 
> > Repeat-By:
> >      Run the following:
> > ....
> >      Ocasionally bash loops at `wait` claiming some "pid is not a child of
> >      this shell". (It doesn't happen if `kill` is not used.)
> 
> Consider this sequence of events. The parent shell forks the last
> asynchronous process and adds it to the jobs array (setting the
> value of $! and adding it to the list of background jobs the shell
> maintains). It then exits and runs its exit trap before the child process
> runs and resets its EXIT trap handler. The parent shell, as part of its
> EXIT trap, kills the last asynchronous child, which still has an active
> EXIT trap, with a SIGTERM. Since the shell is not interactive, SIGTERM is
> a fatal signal. That asynchronous child shell exits, running its EXIT trap.
> 
> The child process, which has an active EXIT trap, has inherited the jobs
> array, the list of background processes, and the value of $! from its
> parent. When it runs its EXIT trap, it will try to wait for all of the
> background jobs it inherited, none of which are its children. You should
> get at least one error message when this happens.
> 
> The loop happens because it keeps trying to wait for these processes that
> are not its children. I'll have to figure out why that's happening --
> probably because it's trying to wait for "all background pids" and not
> doing the right error checks.

-- 
 Félix Hauri  -  <[email protected]>  -  http://www.f-hauri.ch
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.