To me, it is one of the underspecified responsibilities of a standard utility 
implemented as a shell function to use an internal procedure that makes the 
current local state as if a subshell was forked to exec a utility on media, 
including with temporary exports, etc. 

When the shell function finishes execution, I read it as local variables 
created by the function persist because they add to the current variable state, 
but modified variables get restored to the values hidden by that internal 
routine, as non-export values a utilty environment wouldn't have access to, 
plus the previous values of exported variables get restored from the save; by 
use of a separate pseudo-unfork routine. Whether local or exported, temporary 
exports from assigning a variable as part of the invoke should be reverted; 
either unset or reacquire previous value. 

A nice utility implementation will do an explicit unset on variables it creates 
before calling the unfork, so the namespace of the environment isn't polluted 
by these as artifacts, but the standard doesn't require this. As a result the 
wording change cited has to leave things unspecified, with the consequence any 
local variable modifications may persist, even though this is nominally a bug 
for any utility other than a special builtin.


On Monday, June 10, 2019 enh <e...@google.com> wrote:


On Mon, Jun 10, 2019 at 8:56 AM Chet Ramey <chet.ra...@case.edu> wrote:
>
> On 6/10/19 11:38 AM, enh wrote:
> > the toybox project is adding a shell, and came across this issue that
> > i (Android native tools/libraries maintainer) have hit before because
> > mksh does exactly what POSIX says and bash does what POSIX probably
> > intended: 
> > http://lists.landley.net/pipermail/toybox-landley.net/2019-June/010530.html
> >
> > repeated here, lightly edited and extended, because i know there are
> > plenty of shell folks here:
> >
> > I've reached the part of the posix shell stuff (section 2.9.1: simple 
> > commands)
> > that specifies this behavior, and posix doesn't match bash:
> >
> >  If no command name results, or if the command name is a special built-in or
> >  function, variable assignments shall affect the current execution 
> >environment.
> >  Otherwise, the variable assignments shall be exported for the execution
> >  environment of the command and shall not affect the current execution
> >  environment except as a side-effect of the expansions performed in step 4.
>
> This has been changed in the current published version of POSIX, which
> makes the variable persistance behavior unspecified:
>
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01

excellent!

> "If the command name is a function that is not a standard utility
> implemented as a function, variable assignments shall affect the current
> execution environment during the execution of the function. It is unspecified:
>
>    Whether or not the variable assignments persist after the completion of
> the function
>
>    Whether or not the variables gain the export attribute during the
> execution of the function
>
>    Whether or not export attributes gained as a result of the variable
> assignments persist after the completion of the function (if variable
> assignments persist after the completion of the function)"
>
>
>
> >
> > A) This is not what bash does, or has ever done:
> >
> >  $ hello() { echo boing=$BOING; }
> >  $ BOING=123 hello
> >  $ echo $BOING
>
> While this is true for bash in its default mode, bash implements the
> previously-mandated POSIX behavior in POSIX mode:
>
> $ cat x3
> set -o posix
> hello() { echo boing=$BOING; }
> BOING=123 hello
> echo after: $BOING
> $ ../bash-5.0-patched/bash x3
> boing=123
> after: 123
>
> I agree that the default bash behavior is more useful and often what is
> desired (that's why it's the default), and the next version of bash will
> probably make that the default in POSIX mode as well.

yeah, it also seems like the least surprising behavior... when i first
saw this with folks porting from bash to mksh to run on Android, i was
convinced it was a mksh bug because it didn't make any sense that
you'd get different behavior for a function than for an external

command!

> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>                  ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, UTech, CWRU    c...@case.edu    http://tiswww.cwru.edu/~chet/


Reply via email to