If there is anything that needs fixing about this (I haven't checked
the whole standard for all the places where there might be relevant
text) it is to make it more clear that a sub-shell environment cannot
affect the parent shell in any way at all - other than via explicit I/O
(the output from a command substitution, data through pipes, etc),
the exit status of the subshell, and explicit signals/traps.

None of the semi-syntax commands (they're all executable commands) can
possibly have any effect upon anything happening in the parent shell.

If that needs to be made more clear, then it should be done once,
for all of them (break/continue/return/exit) - that is, if, personally
this was never something that ever occurred to me.

Part of the issue might be the way the standard refers to subshell
environment, where what generally happens is a fork - and a whole
new process.  The standard by doing that is trying (for good reason)
to avoid constraining the implementation, things that an implementation
can work out how to do without forking it can do (which will make it
faster, and less expensive to run) - but it must preserve the fiction
that it has forked, as other shells do, and scripts are allowed to
rely upon that, so no side effects (such as a return in a subshell
causing a function in the parent to return) are permitted.

What a return (or break or continue) in a subshell environment (but
not in a function or dot script (or loop for break and continue) in that
subshell does is unspecified.   Some shells make it equivalent to exit,
others ignore it, and others treat it as an error (which would then cause
the sub-shell to exit).   Scripts cannot rely upon anything here, so
should never use return in a subshell (outside of a function called in
that subshell).

Also there is no "scope" really anywhere in the shell, or rather there
is global scope, but that's really it.   For more on this, and why, see
the reply I intend to send soon to Donn Terry's message.

For a couple of explicit statements in this message:

 |  But this is restating the wording of the standard, unless "in a shell
 |  execution environment" means "in a shell execution environment, and not
 |  in a subshell environment thereof",

That is exactly what it means - a subshell environment is a different
environment from the parent shells environment - they do not nest, they
are distinct (and once again, as above, for "execution environment"
think "process" - a "subshell execution environment" is the child of
a shell that has forked, just in standards language).

wrt your possible resolutions:

   a)   the existing 2.14 and 2.95 text means to permit the interpretation
        that 'return' from a function when in a subshell context may just exit
        the subshell and not return from the function;

It cannot exit the function, that's impossible while remaining consistent
with the rest of the standard.   The "may just exit" isn't guaranteed either,
as your oracle stated, what the return there does is unspecified, it might
simply be "nothing".

   b)   the existing 2.14 text is consistent with the observed behaviour
        but the 2.95 text specifying function definition must be changed
        to restrict the types of command that can be used in the definition;

I have no idea what that means - any commands can be used in a function,
the only issue is whether they have specified results or not.   Note that
not everyone cares about that - scripts written for a particular shell can
make use of whatever it happens to do  for what the standard leaves as
unspecified - they just won't be portable.

    c)  the text of 2.14 and 2.95 means what it appears to say

That's correct, but what you believe it appears to say, and what it
actually means, are probably not the same thing.

kre

Reply via email to