[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: wait inside subshell waits for sibling
From: |
Robert Elz |
Subject: |
Re: wait inside subshell waits for sibling |
Date: |
Mon, 24 Oct 2022 18:07:14 +0700 |
Date: Mon, 24 Oct 2022 10:52:22 +0200
From: Emanuele Torre <torreemanuele6@gmail.com>
Message-ID:
<CAA7hNqd-PYW6Oo=hgvAKo8PiUV8eiZVXR007_1tyEyuTpnBv_w@mail.gmail.com>
| I don't see how this is relevant.
See below.
| Process substitutions are considered background jobs, and the wait
| builtin waits for them.
That's fine.
| > That is an entirely different issue, and is working as is supposed
| > to work. That it isn't what some people might expect is irrelevant.
|
| What do you mean?
The ineffectiveness of var modifications in redirects is a direct
result of how they work in general, they've always been (when a
fork is required) evaluated in the subshell (though it is only barely
that, just a forked process between the fork and the exec).
| The problem that was described is caused by that
| optimisation (not the version that is applied to simple commands that
| run external program, but to subshell compound command as mentioned).
I understand that.
| In case you did not understand, the issue is not that "wait inside
| subshell waits for sibling", because the process that runs `cat' IS NOT
| a sibling of the process that runs `wait', it is a CHILD.
I understand that, but you are missing the point. This is where the
"see below" that appeared earlier applies. You're thinking of how it
all exists at the unix process level. And you're probably right (I don't
know bash internals at all) that at that level the process substitution is
a child of the shell environment that is running wait.
But that's not the way we (or the shell) should be looking at this. At
shell script level, the command substitution is not a child of the subshell,
and a wait command in the subshell environment should only see processes
that were created inside that environment, at the shell script level.
Any optimisation should be exactly that - retain the precise effects of
the original code, but run faster (or smaller, or whatever).
If an optimisation alters the way the code works, then it is broken, and
needs to be fixed, or removed.
That's as true of a shell as it is of a compiler, or anything else.
| bash will always evalute (CMDS) REDIRS as (exec REDIRS; CMDS).
That's just fine, but it needs to avoid having anything in REDIRS
affect the execution environment of the subshell.
| To show that this optimisation also affects subshell compound commands,
Once again, examples showing variable modifications made in redirections
are 100% irrelevant, and have no bearing on this.
Let me give you an example
bash -c 'sleep 3 & (wait)'
how long should that run before you get the next prompt back?
3 seconds, or as quickly as the commands involved can be started?
Note that there is absolutely no reason to actually fork to run the
wait command, it is the final command, once wait is done, its subshell
exits, and the script exits - that subshell can be (and in many shells
is) optimised away. I don't know about bash.
But any shell that takes 3 seconds to run that script is broken, as
(wait) as a shell command is identical to (:) as the subshell cannot
possibly have any children, and so that wait cannot possibly have
anything to wait upon.
That the background sleep might have happened to be started in the
same shell environment as the wait command is run, such that its
process is a child of the shell running the wait command is irrelevant.
wait(2) would wait for it, wait(1) must not. That's what I meant
in the previous message about them not being the same thing.
| (CMDS) REDIRS => (exec REDIRS; CMDS) is arguably an incorrect
| optimisation (afaik, only bash peforms it; ksh93 performs the simple
| command optimisation, but not this one),
I would agree, but the optimisation could be fixed, it doesn't need
to be removed.
| but that is what is causing the issue,
I don't care what is causing the issue, that's not my problem, my
only concern is with correct behaviour.
| This is not a problem with the `wait' builtin waiting for a sibling
| since `cat' is not its sibling;
It is. You cannot optimise away a relationship that exists. Anything
that's doing that is reinterpreting the code to mean something different
than what was written, and consequently is broken, and should be fixed.
kre