Re: How is it explained about the `local` is valid variable

2020-11-25 Thread Chet Ramey
On 11/24/20 8:06 PM, Budi wrote:
> Can we validly write a line
> 
> unset local a b c d e f g h i
> 
> to mean:   local a b c d e f g h i;unset a b c d e f g h i

No.

> if yes, how come local=9 is valid variable 'local' normally ? thanks much

Variables and builtin commands are in different namespaces.

-- 
``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: Issue with 'key' for associative arrays

2020-11-25 Thread Greg Wooledge
On Wed, Nov 25, 2020 at 02:48:44PM +0100, Frans de Boer wrote:
> Addressing associative arrays with an array statement - like echo
> ${k["${a[x]}"] does not work.

That seems to work for me, after I fix your quoting.  Using your example
variables:

unicorn:~$ declare -A  k
unicorn:~$ declare -a  a
unicorn:~$ sString="devel packager's guide"
unicorn:~$ i=2
unicorn:~$ k["$sString"]=$i
unicorn:~$ a[$i]=$sString
unicorn:~$ echo "${k[${a[i]}]}"
2

> Next a script to clarify my point:
> ! /bin/bash

This shebang is wrong.

> unset -v 'k["${a[$i]}"]' # does not work

So, it's actually "unset -v" that doesn't work, not echo.

> sTemp=${a[$i]}
> unset -v 'k["$sTemp"]'   # does work

Yeah, I can easily believe that there are bugs or misfeatures hiding
in unset -v.  Personally, I'd avoid it entirely.

If you're using unset -v so that you can do existence testing ("make a
decision based on whether my associative array contains this key or not"),
then you can change that to a simple length test on the value.  Use a
non-empty string as the value.  Then your existence tests becomes
something like:

if [[ ${hash[$key]} ]]; then
  echo "key exists"
fi

If you want to remove a key, just assign an empty string as the value,
rather than trying to use unset -v.

Yes, that's just a workaround to something that might very well be a bug.
You can either wait for a bug fix, and then realize that you still can't
actually USE unset -v in any of your scripts for the next 5-10 years, until
everyone in your target audience is on the fixed version of bash... or
you can use the workaround.

Yes, this doesn't work if you use set -u.  So don't use set -u.



Issue with 'key' for associative arrays

2020-11-25 Thread Frans de Boer

LS,

Unless I have not read the manual properly, bash has an issue with the 
key part used to address a value within associated arrays. I tried this 
in the bash 4.4.x and 5.x series of bash under OpenSUSE 15.2 and TW.


Addressing associative arrays with an array statement - like echo 
${k["${a[x]}"] does not work.
The resulting data from ${a[x]} is technical a string, but is not 
treated as such when using  an associative array. Instead, one should 
first copy the contents of the indexed ${a[x]} array  to an ordinary 
shell variable and then use this variable as the key in an associative 
array.


Next a script to clarify my point:
! /bin/bash

declare -A  k
declare -a  a
declare -i  i=2
declare sString="devel packager's guide"

k["$sString"]=$i
a[$i]=$sString

echo ${k["$sString"]}
echo ${a[$i]}

unset -v 'k["${a[$i]}"]' # does not work
echo ${k["$sString"]}

sTemp=${a[$i]}
unset -v 'k["$sTemp"]'   # does work
echo ${k["$sString"]}

unset -v a[$i]

Is this an intended feature or a possible bug?

--- Frans.

--
A: Yes, just like thatA: Ja, net zo
Q: Oh, Just like reading a book backwards Q: Oh, net als een boek 
achterstevoren lezen
A: Because it upsets the natural flow of a story  A: Omdat het de natuurlijke 
gang uit het verhaal haalt
Q: Why is top-posting annoying?   Q: Waarom is Top-posting zo 
irritant?




Re: How is it explained about the `local` is valid variable

2020-11-25 Thread Greg Wooledge
On Wed, Nov 25, 2020 at 08:06:57AM +0700, Budi wrote:
> Can we validly write a line
> 
> unset local a b c d e f g h i
> 
> to mean:   local a b c d e f g h i;unset a b c d e f g h i

No.  And besides, you would want to unset *first*, right?

What are you actually trying to do here?

> if yes, how come local=9 is valid variable 'local' normally ? thanks much

Because it's a valid assignment to a perfectly acceptable variable.

It's the same as:

cd=42
cd /tmp

There's no conflict.  The first one is an assignment to a variable named
cd.  The second one is a cd command.



Re: increment & decrement error when variable is 0

2020-11-25 Thread felix
On Mon, Nov 23, 2020 at 05:20:22PM -0500, Greg Wooledge wrote:
> On Mon, Nov 23, 2020 at 07:36:29PM +, Jetzer, Bill wrote:
>...
> Exercises 1 and 2 apply directly...

>From man bash:
   ((expression))
  The expression is evaluated according to the rules described be‐
  low under ARITHMETIC EVALUATION.  If the value of the expression
  is non-zero, the return status is 0; otherwise the return status
  is 1.  This is exactly equivalent to let "expression".

So little modified test/demo:

for ((i=-100; i<100; i++)) ;do
x=$i
((v = --x ,v)) || echo "err code $? on --x going from $i to $x -> $v"
x=$i
((v = x-- ,v)) || echo "err code $? on x-- going from $i to $x -> $v"
x=$i
((v = ++x ,v)) || echo "err code $? on ++x going from $i to $x -> $v"
x=$i
((v = x++ ,v)) || echo "err code $? on x++ going from $i to $x -> $v"
done

Will render near same output:

err code 1 on ++x going from -1 to 0 -> 0
err code 1 on x-- going from 0 to -1 -> 0
err code 1 on x++ going from 0 to 1 -> 0
err code 1 on --x going from 1 to 0 -> 0

Where *when the value of the expression is zero, the return status is 1*.

Difference between ((x--)) and ((--x)) is only usefull when *using* this
variable simultaneously while decrementing them (for assignment, testing,
or printing):

i=10;while ((i));do echo $i;((i--));done
and
i=10;while ((i));do echo $i;((--i));done
will do same result.
But
i=10;while ((i));do echo $((i--));done  # return 10 to 1
i=10;while ((i));do echo $((--i));done  # print 9 to 0
or
i=10;while ((i--));do echo $i;done   # print 9 to 0
i=10;while ((--i));do echo $i;done   # print 9 to 1 (exit at 0 before print)

-- 
 Félix Hauri  --  http://www.f-hauri.ch