bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bash-5.0: problem with variable scoping in posix-mode


From: Chet Ramey
Subject: Re: bash-5.0: problem with variable scoping in posix-mode
Date: Wed, 20 Mar 2019 10:16:07 -0400

> > Description:
> > 
> > There is a problem with variable scoping when variable is created from
> > assignment statement preceding function call in posix-mode. See an
> > example below.
> > 
> > 
> > Repeat-By:
> > 
> > $ cat test.sh 
> > #!/bin/sh
> > 
> > myecho() {
> >     echo $var
> > }
> > 
> > foo() {
> >     local var="foo: FAIL"
> >     var="foo: bar" myecho
> > }
> > 
> > foo
> > 
> > $ bash test.sh 
> > foo: bar
> > $ bash --posix test.sh 
> > foo: FAIL
> 
> This is a consequence of a combination of two POSIX features. First, POSIX
> requires assignment statements preceding special builtins to create global
> variables (POSIX has no local variables) that persist in the shell context
> after the special builtin completes. Second, POSIX requires* that
> assignment statements preceding function calls have the same variable-
> assignment behavior as special builtins.
> 
> So the variable assignment preceding the function call creates a global
> variable, and the local variable is found before that global when `myecho'
> is executed according to the standard bash dynamic scoping rules. If you
> add an `echo $var' after the call to foo, you'll see this behavior.
> 
> (*) The most recent version of the standard has removed this requirement
> for shell functions, and I will change that behavior for the next release
> of bash. Until then, the old behavior persists.

This behavior is not quite backwards-compatible with bash-4.4. Here is a
patch that implements a portion of the proposed bash-5.1 behavior. It
changes the variable assignment semantics so that variable assignments
preceding builtins and shell functions act more like standalone assignment
statements and modify the "current execution environment" (in POSIX terms)
instead of unconditionally modifying the global variable scope.

This means that assignments preceding shell functions and special builtins
will modify existing local variables and modifications to local variables
will not propagate to the calling environment, and will create global
variables if there is not an existing local variable with that name. This
is compatible with other POSIX shells that implement local variables.

It is not completely compatible with bash-4.4, since the bash-4.4 behavior
wasn't fully POSIX-conformant and had variable scoping bugs as well.

The original discussion concerning this is at

http://lists.gnu.org/archive/html/bug-bash/2018-05/msg00002.html

Chet

Attachment: assignment-preceding-builtin.diff
Description: Text document

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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]