On 10/20/16 2:45 PM, kjk...@gmail.com wrote:
> set -x
> 
> var_123=123
> f() {
>     while (( $# )); do
>         shift
>         local var=var_123
>         local -n var=$var; : status is $?
>         local -p
>         : var is $var
>     done
> }
> 
> f one two
> 
> 
> Running above script gives the follow output:
> 
> + var_123=123
> + f one two
> + ((  2  ))
> + shift
> + local var=var_123
> + local -n var=var_123

`var' is a local nameref with value var_123

> + : status is 0
> + local -p
> var=var_123
> + : var is 123

Since var is a nameref, it expands to $var_123, which is 123

> + ((  1  ))
> + shift
> + local var=var_123

var doesn't get unset; it's still a nameref with value var_123.  Setting
the local attribute on an existing local variable doesn't unset any of
the variable's attributes.  You have to actually unset the variable to
do that.

> + local -n var=123
> ./x.sh: line 10: local: `123': invalid variable name for name reference

So now you try to assign `123' as the value of a nameref.  That would
cause subsequent attempts to assign to var to attempt to create and
assign to a variable named `123', which is invalid.  Bash-4.3 didn't
have enough error checking and would create variables with invalid names
in situations like this.

> + : status is 1
> + local -p
> var=var_123

This is probably where the confusion comes.  `local -p' doesn't print other
variable attributes.  If you had used `declare -p | grep var=' between the
two calls to `local' you would have seen that `var' had the nameref
attribute.

> + : var is 123
> + ((  0  ))

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://cnswww.cns.cwru.edu/~chet/

Reply via email to