bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: wait inside subshell waits for sibling


From: Emanuele Torre
Subject: Re: wait inside subshell waits for sibling
Date: Mon, 24 Oct 2022 04:25:44 +0200

I don't think the process running `cat' is a sibling of the subshell.

bash performs an optimisation that runs redirections applied to simple
commands that run external programs, or subshell compound commands after
the fork(). (to avoid having to restore file descriptors after running
the command.)

This causes other weird pitfalls, e.g. the following script loops
infinitely, and always runs `sleep 1 > /tmp/file1':

    i=0
    while [ "$i" -lt 10 ]
        do sleep 1 > "/tmp/file$(( ++i ))"
    done

On 23/10/2022, Oğuz İsmail Uysal <oguzismailuysal@gmail.com> wrote:
> To reproduce:
>
>     $ echo $BASH_VERSION
>     5.2.2(3)-release
>     $ ( : & wait ) > >(cat)
>     *hangs*
>
> It should return immediately, but hangs instead.

This behaviour has existed for a while in bash, it was not introduced in
5.2.

It causes many pitfalls that are hard to spot; see [1] (which I just
updated to mention a problematic use case like yours), and [2].

[1]: <https://mywiki.wooledge.org/BashPitfalls#pf64>
[2]: https://www.vidarholen.net/contents/blog/?p=865

I have never encountered a problem like the one you described before,
but that is probably one of the worse pitfalls caused by this
optiomisation. :^)

Effectively, because of the optimisation, your command is run like:

    (exec > >(cat); : & wait)

So the subshell process that runs `cat' is a child of the subshell that
runs `: & wait', so wait will also wait for it.

To inhibit this optimisation, you can wrap your subshell compound
command (or simple command) in a group command, and apply the
redirections to it instead of the subshell command:

    { (: & wait) ;} > >(cat)

Or, in your specific case, use "$!" to only wait for the most recent
background job.

    (: & wait -- "$!") > >(cat)

Cheers.
 emanuele6



reply via email to

[Prev in Thread] Current Thread [Next in Thread]