Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}
On 10/28/16 3:43 PM, L. A. Walsh wrote: > >Please, I'm not running in posix mode, so how would their rules > apply? Because you're using `bash', not `walsh'? Bash is a posix shell. Would the bash documentation convince you? You could go read that instead. > Just because posix defines something a certain way > doesn't mean it should apply in a non-posix mode shell. Come on, don't be willfully obtuse. You know better than this. Posix mode doesn't mean "turning it off does everything the way Linda wants." -- ``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?
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: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}
Chet Ramey wrote: On 10/24/16 7:32 PM, L. A. Walsh wrote: I don't understand the ambiguity. If param= "#obj[@]", then it is clear to me that the user wants the length of an array named "obj". Stop there. In something like ${#obj[@]}, `param' is `obj[@]'. The `${#param}' is a clearly-defined word expansion, separate from the `[:]-' forms: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02 That's what we're talking about here. Please, I'm not running in posix mode, so how would their rules apply? Just because pi=3 under Indiana state rules some number of years ago, doesn't mean it is. Just because posix defines something a certain way doesn't mean it should apply in a non-posix mode shell.
Re: Race in bash-4.3 'typeset'?
Op 28-10-16 om 15:00 schreef Chet Ramey: > On 10/25/16 12:40 AM, Martijn Dekker wrote: >> Try simply testing the exit status of 'typeset -p' or 'declare -p'. If >> the variable is not declared, it exits unsuccessfully. >> >> if typeset -p "$var" >/dev/null 2>&1 && [[ ! -v $var ]] >> then ... >> >> As far as I can tell, this is not documented in 'help' or in the info >> page, by the way. Perhaps it should be. > > It's documented. The man page, for instance, says: > > "The return value is 0 unless ... one of the names is not a valid shell > variable name" > > which handles both the "not correctly formed" and "not found" cases. To me that seems like a far-fetched interpretation. The way I read it, if a variable is not declared, that does not imply its name is not valid. An invalid name would mean it is impossible to declare it. I think adding ", the variable is not declared" would prevent misunderstandings. - M.
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: Race in bash-4.3 'typeset'?
On 10/25/16 12:19 PM, Stuart Shelton wrote: > Thanks for the suggestion! > > However, it doesn’t appear to be able to detect local variables (is this > intentional or a bug?): It's a bug; fixed in bash-4.4. 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: Race in bash-4.3 'typeset'?
On 10/25/16 12:40 AM, Martijn Dekker wrote: > Op 25-10-16 om 00:42 schreef Stuart Shelton: >> Failing this, is there any alternative to ‘typeset’ to list a >> variable declared as local to a function but which has not yet been >> assigned a value? > > Try simply testing the exit status of 'typeset -p' or 'declare -p'. If > the variable is not declared, it exits unsuccessfully. > > if typeset -p "$var" >/dev/null 2>&1 && [[ ! -v $var ]] > then ... > > As far as I can tell, this is not documented in 'help' or in the info > page, by the way. Perhaps it should be. It's documented. The man page, for instance, says: "The return value is 0 unless ... one of the names is not a valid shell variable name" which handles both the "not correctly formed" and "not found" cases. -- ``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: Race in bash-4.3 'typeset'?
On 10/25/16 4:09 PM, Stuart Shelton wrote: > The cases appear, purely by inspection, to be: > > Not declared: trivially, `typeset -p` doesn’t include the value; > Declared (even as local) but unassigned: `typeset -p` includes "declare -- > varname"; > Declared and assigned: `typeset -p` includes "declare -- varname=‘value’” > > … although how much of this is by design and how much by chance I’m not sure > ;) It's all by design. The idea is that you can use `typeset -p' to save and restore the variable state. It's imperfect, I'm sure, and there are probably missing edge cases, but that's the idea. -- ``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: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}
On 10/24/16 7:32 PM, L. A. Walsh wrote: >I don't understand the ambiguity. If param= "#obj[@]", then it > is clear to me that the user wants the length of an array named "obj". Stop there. In something like ${#obj[@]}, `param' is `obj[@]'. The `${#param}' is a clearly-defined word expansion, separate from the `[:]-' forms: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02 That's what we're talking about here. -- ``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/