Re: Is this the expected behaviour for nameref in Bash 4.4 now?
thank you for the insight, it's very helpful! On Oct 28, 2016 10:01 AM, "Chet Ramey"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, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~ chet/
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
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, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
On 10/20/16 7:44 PM, Jack Kuan wrote: > Thanks for replying. > > I was expecting that in the second iteration of the loop, the > local var=var_123 command would make var a normal variable again with > value "var_123" This is the bad assumption. You didn't unset `var' before doing this, so it retains its local attribute and its nameref attribute. Trying to make a local variable from an already-local variable is a no-op. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Is this the expected behaviour for nameref in Bash 4.4 now?
Yes that was an intentional change to require valid identifiers. I can't say it will always be that way or that there won't at some point be a workaround. You can stiill use `${!param}' for now to refer to positional parameters as you always could, but as usual that isn't useful if you want to assign by reference.
Is this the expected behaviour for nameref in Bash 4.4 now?
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 + : status is 0 + local -p var=var_123 + : var is 123 + (( 1 )) + shift + local var=var_123 + local -n var=123 ./x.sh: line 10: local: `123': invalid variable name for name reference + : status is 1 + local -p var=var_123 + : var is 123 + (( 0 )) With Bash 4.3 the output is: + var_123=123 + f one two + (( 2 )) + shift + local var=var_123 + local -n var=var_123 + : status is 0 + local -p var=var_123 + : var is 123 + (( 1 )) + shift + local var=var_123 + local -n var=var_123 + : status is 0 + local -p var=var_123 + : var is 123 + (( 0 )) Thanks Jack