Re: set -u not working as expected

2020-08-02 Thread Chet Ramey
On 8/2/20 4:01 AM, Oğuz wrote:

> $ set -u
> $ unset foo bar
> $ typeset -i foo bar
> $
> $ foo+=foo+1
> $
> $ foo+=bar+1
> bash: bar: unbound variable
> 
> Only referencing `bar' triggers the _unbound variable_ error, it makes
> sense that the name being assigned is immune to that.

You could make a decent case that this is a bug in bash, I suppose, but
I am comfortable with the current behavior.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: set -u not working as expected

2020-08-02 Thread Chet Ramey
On 8/2/20 3:34 AM, Lawrence Velázquez wrote:

>>> % bash -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
>>> <1>
>>> % ksh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
>>> <1>
>>> % zsh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
>>> <1>
> 
> ...which contrasts with the behavior of let. Someone else will have
> to explain this, as I don't know what to make of it.

The integer attribute means the rhs of the assignment operator is
evaluated as an expression. It doesn't mean the assignment is performed
in an arithmetic context, as with `let' or `$((...))'. The special case,
which is done to conform to user expections, is that the result is added
to the current value, if any, instead of being appended like the usual
behavior of `+='. Note that there are no corresponding `name*=value' or
`name-=value' variable assignment operators, and that `-u' isn't in
effect for any use of `+=', whether the integer attribute is present or
not.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: set -u not working as expected

2020-08-02 Thread Chet Ramey
On 8/1/20 8:47 PM, Lawrence Velázquez wrote:

>> let v+=1 # Line 18, Once line 11 is uncommented, Bash fails here
> 
> I haven't seen the code for arithmetic expansion, but I assume it
> treats v+=1 as morally equivalent to v=${v}+1 (à la C99). Thus there
> *is* an expansion, which fails under set -u. Regardless of the
> particulars, ksh and zsh again agree:

This is indeed what happens in an arithmetic context. It happens with
pre- and post-increment and decrement operators, too.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: set -u not working as expected

2020-08-02 Thread Chet Ramey
On 8/1/20 2:48 PM, Kristof Burek wrote:

> Bash Version: 5.0
> Patch Level: 3
> Release Status: release
> 
> (Machine is a Raspberry Pi running Raspbian "Buster")
> 
> Description:
> After set -u in a script: when x has not yet been bound to a value, 
> I would expect the statements x+='x' and x+=('x') to cause Bash to
> report an error and exit the script.  But it does not.

This does not fall under the `expand an unset parameter' scope where the
`-u' option is active.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Re: set -u not working as expected

2020-08-02 Thread Oğuz
However,

> In arithmetic evaluation context, if a variable for which the integer
attribute is set appears at the LHS of an assignment operator, it shouldn't
be expanded.

would be a reasonable feature request I guess.


-- 
Oğuz


Re: set -u not working as expected

2020-08-02 Thread Oğuz
2 Ağustos 2020 Pazar tarihinde Lawrence Velázquez  yazdı:

> > On Aug 2, 2020, at 2:51 AM, Oğuz  wrote:
> >
> > `u' has no members, so there's nothing to expand. If you use `${u[0]}'
> for
> > example, you'll see an error, I think how bash and ksh behave is
> perfectly
> > reasonable.
>
> Agreed. Their behavior logically follows from POSIX's carveout for $@.
>
> >> % bash -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
> >> bash: v: unbound variable
> >> % ksh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
> >> ksh: v: parameter not set
> >> % zsh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
> >> <0>
> >>
> >>
> > `typeset -i v' doesn't assign `v', just gives it the integer attribute.
> > Again, I can't see any problem with bash and ksh here.
>
> Also agreed, but I was more interested in the next part...
>
> >> % bash -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
> >> <1>
> >> % ksh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
> >> <1>
> >> % zsh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
> >> <1>
>
> ...which contrasts with the behavior of let. Someone else will have
> to explain this, as I don't know what to make of it.
>
>
Yeah, that's interesting. See this one:

$ set -u
$ unset foo bar
$ typeset -i foo bar
$
$ foo+=foo+1
$
$ foo+=bar+1
bash: bar: unbound variable

Only referencing `bar' triggers the _unbound variable_ error, it makes
sense that the name being assigned is immune to that.

Concerning `let v+=1', let is not a declaration utility, it's arguments are
arithmetic expressions to be evaluated. And in arithmetic evaluation
context:

> Shell variables are allowed as operands; parameter expansion
> is performed before the expression is evaluated.


> vq



-- 
Oğuz


Re: set -u not working as expected

2020-08-02 Thread Lawrence Velázquez
> On Aug 2, 2020, at 2:51 AM, Oğuz  wrote:
> 
> `u' has no members, so there's nothing to expand. If you use `${u[0]}' for
> example, you'll see an error, I think how bash and ksh behave is perfectly
> reasonable.

Agreed. Their behavior logically follows from POSIX's carveout for $@.

>> % bash -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
>> bash: v: unbound variable
>> % ksh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
>> ksh: v: parameter not set
>> % zsh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
>> <0>
>> 
>> 
> `typeset -i v' doesn't assign `v', just gives it the integer attribute.
> Again, I can't see any problem with bash and ksh here.

Also agreed, but I was more interested in the next part...

>> % bash -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
>> <1>
>> % ksh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
>> <1>
>> % zsh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
>> <1>

...which contrasts with the behavior of let. Someone else will have
to explain this, as I don't know what to make of it.

vq


Re: set -u not working as expected

2020-08-01 Thread Oğuz
2 Ağustos 2020 Pazar tarihinde Lawrence Velázquez  yazdı:

> > On Aug 1, 2020, at 8:47 PM, Lawrence Velázquez  wrote:
> >
> > Presumably none of these shells implements u+=(t) as u=("${u[@]}" t).
>
> Granted, they do disagree on ${u[@]}.
>
> % bash -c 'set -u; unset u; u=("${u[@]}" t); typeset -p u'
> declare -a u=([0]="t")
> % ksh -c 'set -u; unset u; u=("${u[@]}" t); typeset -p u'
> typeset -a u=(t)
> % zsh -c 'set -u; unset u; u=("${u[@]}" t); typeset -p u'
> zsh:1: u[@]: parameter not set
>
>
`u' has no members, so there's nothing to expand. If you use `${u[0]}' for
example, you'll see an error, I think how bash and ksh behave is perfectly
reasonable.


> > I haven't seen the code for arithmetic expansion, but I assume it
> > treats v+=1 as morally equivalent to v=${v}+1 (à la C99). Thus there
> > *is* an expansion, which fails under set -u. Regardless of the
> > particulars, ksh and zsh again agree:
> >
> > % bash -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
> > bash: v: unbound variable
> > % ksh -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
> > ksh: let: v: parameter not set
> > ksh: v: parameter not set
> > % zsh -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
> > zsh:1: v: parameter not set
> > zsh:1: v: parameter not set
>
> On the other hand...
>
> % bash -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
> bash: v: unbound variable
> % ksh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
> ksh: v: parameter not set
> % zsh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
> <0>
>
>
`typeset -i v' doesn't assign `v', just gives it the integer attribute.
Again, I can't see any problem with bash and ksh here.


> ...and...
>
> % bash -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
> <1>
> % ksh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
> <1>
> % zsh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
> <1>
>
> *shrug*
>
> vq
>


-- 
Oğuz


Re: set -u not working as expected

2020-08-01 Thread Lawrence Velázquez
> On Aug 1, 2020, at 8:47 PM, Lawrence Velázquez  wrote:
> 
> Presumably none of these shells implements u+=(t) as u=("${u[@]}" t).

Granted, they do disagree on ${u[@]}.

% bash -c 'set -u; unset u; u=("${u[@]}" t); typeset -p u'
declare -a u=([0]="t")
% ksh -c 'set -u; unset u; u=("${u[@]}" t); typeset -p u'
typeset -a u=(t)
% zsh -c 'set -u; unset u; u=("${u[@]}" t); typeset -p u'
zsh:1: u[@]: parameter not set

> I haven't seen the code for arithmetic expansion, but I assume it
> treats v+=1 as morally equivalent to v=${v}+1 (à la C99). Thus there
> *is* an expansion, which fails under set -u. Regardless of the
> particulars, ksh and zsh again agree:
> 
> % bash -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
> bash: v: unbound variable
> % ksh -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
> ksh: let: v: parameter not set
> ksh: v: parameter not set
> % zsh -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
> zsh:1: v: parameter not set
> zsh:1: v: parameter not set

On the other hand...

% bash -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
bash: v: unbound variable
% ksh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
ksh: v: parameter not set
% zsh -c 'set -u; typeset -i v; printf "<%s>\\n" "$v"'
<0>

...and...

% bash -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
<1>
% ksh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
<1>
% zsh -c 'set -u; typeset -i v; v+=1; printf "<%s>\\n" "$v"'
<1>

*shrug*

vq


Re: set -u not working as expected

2020-08-01 Thread Lawrence Velázquez
> On Aug 1, 2020, at 2:48 PM, Kristof Burek  wrote:
> 
> set -u  # Bash complains and exits on first use of an unbound name

With respect to set -u neither the bash man page nor POSIX.1-2017
refer to "use" of parameters, but to their *expansion*.

> s+='t' # Line 8 - Bash should fail here

I don't see any parameter expansion here, and ksh and zsh agree:

% bash --version | head -n 1; ksh --version; zsh --version
GNU bash, version 5.0.17(1)-release (x86_64-apple-darwin18.7.0)
  version sh (AT&T Research) 93u+ 2012-08-01
zsh 5.8 (x86_64-apple-darwin18.7.0)
% bash -c 'set -u; unset s; s+=t; printf "<%s>\\n" "$s"'

% ksh -c 'set -u; unset s; s+=t; printf "<%s>\\n" "$s"'

% zsh -c 'set -u; unset s; s+=t; printf "<%s>\\n" "$s"'


Presumably none of these shells implements s+=t as s=${s}t.

> #t=''
> t=${t}'t' # Line 12, Bash fails until line 11 loses its starting #

This fails as you expect because you're expanding $t in there.

> u+=('t') # Line 15, Bash should fail here

Again, I don't see any parameter expansion here, and ksh and zsh
agree:

% bash -c 'set -u; unset u; u+=(t); printf "<%s>\\n" "${u[@]}"' 

% ksh -c 'set -u; unset u; u+=(t); printf "<%s>\\n" "${u[@]}"' 

% zsh -c 'set -u; unset u; u+=(t); printf "<%s>\\n" "${u[@]}"' 


Presumably none of these shells implements u+=(t) as u=("${u[@]}" t).

> let v+=1 # Line 18, Once line 11 is uncommented, Bash fails here

I haven't seen the code for arithmetic expansion, but I assume it
treats v+=1 as morally equivalent to v=${v}+1 (à la C99). Thus there
*is* an expansion, which fails under set -u. Regardless of the
particulars, ksh and zsh again agree:

% bash -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
bash: v: unbound variable
% ksh -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
ksh: let: v: parameter not set
ksh: v: parameter not set
% zsh -c 'set -u; unset v; let v+=1; printf "<%s>\\n" "$v"'
zsh:1: v: parameter not set
zsh:1: v: parameter not set

> When this issue is fixed, I dare say a few perfectly working scripts
> will fall over, but I hope not too many of mine.

It's not clear that there's a bug here.

vq