On Fri, Dec 12, 2025, 19:20 Robert Elz <[email protected]> wrote:

> I'm guessing that the difference between using awk, and most other
> processes that might be used (echo, sed, even cat probably) inside the
> cmdsub, is that awk (gawk) might be doing
>
>         freopen(filename, "r", stdin);
>
> or something similar, which it is perfectly entitled to do (ie: doing that
> is certainly not, of itself, a bug).

What gawk had was essentially a call like:

    fcntl(2, F_SETFL, fcntl(2, F_GETFL) | O_APPEND);

> Even assuming that in the subshell
> environment, bash implements the above as if it were "exec awk" (which it
> probably does), that is still in a subshell environment, and should not be
> able to affect the parent shell environment, nor any command it starts
later
> (such as the final "cat" above), not counting what the cmdsub writes to
its
> stdout of course.

...and, it seems, any changes to the file offset or file flags associated
with inherited file descriptors.

So executing gawk, even in a subshell, would add O_APPEND to the
file status flags of FD 2 of the parent.

Compare normal behavior:

    $ echo abc >foo; (echo def) 1<>foo 2>&1
    $ cat foo
    def

and same steps with a dummy gawk invocation added:

    $ echo abc >foo; ((gawk ''); echo def) 1<>foo 2>&1
    $ cat foo
    abc
    def

Instead of gawk, you could use a program that just does the fcntl call
above.

> That's what knowing what happens if dash were to execute the same command
> would reveal - if the same problem occurs, then I'd say there's a kernel
bug,
> and simply ignore the issue here (that is, wrt bash).

All other shells I tried on Linux and macOS behave the same: an F_SETFL
in a subshell affects the flags of the FD in the parent.

The removed gawk code was prefaced with the following explanation, which
I don't really understand, but it does suggest some difference in behavior
between systems in this area. Which behavior, if any, can be considered a
bug I do not know.

    // 1/2018: This is needed on modern BSD systems so that the
    // inplace tests pass. I think it's a bug in those kernels
    // but let's just work around it anyway.

Reply via email to