thank you for the insight, it's very helpful! On Oct 28, 2016 10:01 AM, "Chet Ramey" <chet.ra...@case.edu> wrote:
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/