Date: Mon, 24 Oct 2022 10:52:22 +0200 From: Emanuele Torre <torreemanue...@gmail.com> Message-ID: <CAA7hNqd-PYW6Oo=hgvako8piuv8eizvxr007_1tyeyutpnb...@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