Re: Race in bash-4.3 'typeset'?
> On 25 Oct 2016, at 05:40, 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. > > Also note that, while zsh and yash share this behaviour, ksh93 and > mksh/pdksh do not. If you want to be compatible with all the shells that > support 'typeset', you could do: > >if [ -n "$(typeset -p "$var" 2>/dev/null)" ] && > eval "[ -z \"\${var+s}\" ]" >then ... > > which is slower because it uses a subshell. > > HTH, > > - M. > Hi Martijn, Thanks for the suggestion! However, it doesn’t appear to be able to detect local variables (is this intentional or a bug?): $ test() { local testvar echo “typeset test:" typeset -p testvar && echo yes || echo no echo “grep test:" typeset -p | grep testvar } $ test typeset test: -bash: typeset: testvar: not found no grep test: declare -- testvar yes Cheers, Stuart
Re: Race in bash-4.3 'typeset'?
What version of bash are you using Stuart? typeset -p should work for local variables too in any recent bash version.
Re: Race in bash-4.3 'typeset'?
> On 25 Oct 2016, at 17:36, Eduardo Bustamante wrote: > > What version of bash are you using Stuart? typeset -p should work for > local variables too in any recent bash version. typeset omitting existing variables or failing and causing a SIGPIPE I’ve seen with Ubuntu 14.04 LTS’ bash-4.3.11(1). The immediately prior example (where variables declared local but unset in terms of value weren’t causing typeset to return successfully) was run on Ubuntu 16.10’s bash-4.3.46(1). This later version doesn’t seem to be affected by the apparently non-deterministic original problem, however. I’ve not seen any case where calling typeset again immediately after having called it and received an anomalous response doesn’t respond correctly - so my current solution is simply to invoke typeset twice… but the presence of this discrepancy is worrying. If this isn’t expected bash-4.3 behaviour, then it’s entirely possible that Canonical are doing something strange here, of course...
Re: Race in bash-4.3 'typeset'?
Ah! You're right. The second issue was already reported back in 2015 https://lists.gnu.org/archive/html/bug-bash/2015-02/msg00060.html Now, regarding the SIGPIPE issue. The message bash is printing just means that grep closed the pipe, so the bash process receives a SIGPIPE when attempting to write. The output of strace (make sure you use -f to follow forks) will make things easier to find out where the issue is.
Re: Race in bash-4.3 'typeset'?
Stuart Shelton wrote: I have some code which evals a configuration file - but before doing so attempts to validate the content. It does this by taking each potential keyword from the file and then doing: if typeset -p | grep -q "^declare -. ${var}$”; then … to determine whether the keyword in question exists as a declared but unset variable in the script. --- I don't think you can do that, primarily because you can't see the fact that something is declared but unset. "typeset -p" displays "attributes" AND "values". If the variables has no value, then how would it display that? Also, in the above, what if the variable is declared as an integer and exported? Your grep-expression won't match, as it only allows for 1 flag. You might want to use grep -Pq and put a "+" after the "-." Also, what is ${var} supposed to contain? I'm guessing that var isn't your variable you are testing for but maybe the name of the var? I've had that confusion in some scripts where I had functions taking arrays of 'var' -- which for some meant arrays of values, but in other cases I needed the names of the vars that contained those values. I ended up with a weak rule to try to always append "nam[e]" or "str[ing]" to things that were to be interpreted as names or strings, then using nothing, or 'ptr' or 'ref' on the end to indicate it was a reference to the value, like: var=33 varname=var echo "name of var=$varname, value=$var" Anyway, even if you fixed the regex, I think you'll have problems trying to detect unset variables... problems due to my 1st paragraph, above However, I am seeing cases where the above incorrectly fails, or where executing this line twice in immediate succession will fail on the first invocation and then succeed on the second. Is it being assigned a value between invokations? -l
Re: Race in bash-4.3 'typeset'?
> On 25 Oct 2016, at 20:45, L. A. Walsh wrote: > Stuart Shelton wrote: >> I have some code which evals a configuration file - but before doing so >> attempts to validate the content. It does this by taking each potential >> keyword from the file and then doing: >> >> if typeset -p | grep -q "^declare -. ${var}$”; then >> >> … to determine whether the keyword in question exists as a declared but >> unset variable in the script. >> > --- > I don't think you can do that, primarily because > you can't see the fact that something is declared but unset. > "typeset -p" displays "attributes" AND "values". If the variables has > no value, then how would it display that? 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 ;) > Also, in the above, what if the variable is declared as an > integer and exported? Your grep-expression won't match, as > it only allows for 1 flag. You might want to use grep -Pq and > put a "+" after the "-." This is a very good point - I only coded for the cases I’ve seen, and the single-flag situation covers this. I will update it, though, to reflect the wider range of possible values... > Also, what is ${var} supposed to contain? I'm guessing that var > isn't your variable you are testing for but maybe the name of the > var? Yes, in this case ‘var’ is a loop-variable which cycles through each keyword in the configuration file to be validated. > I've had that confusion in some scripts where I had functions taking > arrays of 'var' -- which for some meant arrays of values, but in > other cases I needed the names of the vars that contained those values. > I ended up with a weak rule to try to always append "nam[e]" or "str[ing]" > to things that were to be interpreted as names or strings, then > using nothing, or 'ptr' or 'ref' on the end to indicate it was > a reference to the value, like: > > var=33 > varname=var > echo "name of var=$varname, value=$var" Also a very good point :) >> However, I am seeing cases where the above incorrectly fails, or where >> executing this line twice in immediate succession will fail on the first >> invocation and then succeed on the second. > > Is it being assigned a value between invokations? Nope - literally run the same command twice in immediate succession, and the output differs, with the first omitting any value or causing a SIGPIPE to be generated, and the second with the expected value which reflects the environment. The second call always appears to do the right thing, though - and given that a sleep before (or between, although the second case has always succeeded) the command appears to have no effect, I wonder whether there’s some counter or flag not being updated correctly?
Re: Race in bash-4.3 'typeset'?
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 ;) Hmmm... you're right. I guess it's my mind remembering that it is "unbound" and trying to use it under "-u" will yield an error (so I always try to set a value when declaring it, as declaring it, alone doesn't "bind" it...)... *kick self for even opening mouth...*... :-) I'm too used to programming with -u to detect unset vars...(which are usually the result of typo's like: test=1 if [[ $tst eq 1 ]];then echo "so? wrong var"; fi Now if I were perfect, I wouldn't be using "-u". ;-)
Re: Race in bash-4.3 'typeset'?
Op 25-10-16 om 18:19 schreef Stuart Shelton: > However, it doesn’t appear to be able to detect local variables (is this > intentional or a bug?): Strange. Works for me on bash 3.2.57 and bash 4.4.0 (Mac OS X) and bash 4.2.53 and 4.1.17 (Linux). - M.