Re: Race in bash-4.3 'typeset'?

2016-10-25 Thread Stuart Shelton

> 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'?

2016-10-25 Thread Eduardo Bustamante
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'?

2016-10-25 Thread Stuart Shelton

> 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'?

2016-10-25 Thread Eduardo Bustamante
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'?

2016-10-25 Thread L. A. Walsh



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'?

2016-10-25 Thread Stuart Shelton

> 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'?

2016-10-25 Thread L. A. Walsh



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'?

2016-10-25 Thread Martijn Dekker
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.