[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Awkward behavior of empty arrays
From: |
Cristian Zoicas |
Subject: |
Re: [Help-bash] Awkward behavior of empty arrays |
Date: |
Thu, 7 Sep 2017 11:31:01 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/20100101 Firefox/43.0 SeaMonkey/2.40 |
> Hm, interesting. I think your whole message below can be rephrased as: empty
arrays don't work with set -u. Is that right?
right...
> If so I agree, and I would consider that a design problem.
... but I prefer this sentence containing the expression "design problem"
instead
of "empty arrays don't work with set -u". And I would also add the following
problems:
* "declare -a A=" creates an array with a single null element;
* the manual should clarify some missing issues.
> I just tested mksh and it does the same thing as bash. (mksh is a pksh fork, and
pdksh was a clone of AT&T ksh, so I
> suspect the behavior originated there.)
>
Probably the original designers wanted to allow for the possibility of using an
empty array (e.g. declare -a A=() )
at least in a minimal way so they decided that the compromise of allowing to
test the length of the array but not
the use expansion is a good one. It could makes sense if you don't want to
allow empty arrays, but I cannot understand
why such arrays should be not allowed.
> set -u is useful with arrays for out-of-bounds checks:
>
> $ set -u
> $ declare -a A=(1 2 3)
> $ echo "${A[2]}"
> $ echo "${A[3]}"
> -bash: A[3]: unbound variable
excelent example. I've not imagined/used set -u for out-of-bound checks.
> But I agree that the empty array check is undesired. It's also inconsistent
with the argv array:
>
> $ set -u
> $ set -- # clear argv array
> $ echo "$#"
> 0
> $ argv "$@" # gives desired empty array of argument, not error
> []
I would call this inconsistency another "design problem". Here is another
awkward example based on it:
set -u;
for p in "$@"; do echo "$p"; done
declare -a A=( "$@" )
for p in "address@hidden"; do echo "$p"; done
echo address@hidden
Anything works well until the @ array is empty.
$@ behaves very well (I would say perfectly) with respect to the for
loop even when it is empty. In the example below
set -u;
set --;
for i in "$@"; do
echo "i=${i}";
done
The statements in the for loop are not iterated.
I want to use this occasion to mention another issue related to the expanssion
of the single possible
empty array, $@, (because it is not possible to expand other empty arrays when
set -u.)
Lets' see what happens in the following cases:
1) unset A; declare A=; for v in ${A}; do echo "v="; done
# A is declared WITHOUT the array attribute. The statements in the for loop
are not executed because $A expands to nothing.
2) unset A; declare A=; for v in "${A}"; do echo "v="; done
# A is declared WITHOUT the array attribute . The statements in the for loop
*are* executed (it
# is not a problem). bash sees the first " and considers it the beginning of
a string. Inside the
# string there is A must be expanded. It expands to null. After A the string
finishes and thus we
# get a zero length string.
3) set -u; set -- A B C; for s in "address@hidden"; do echo "s=${s}"; done
# It prints : "s=XA s=B s=CY" and it behaves as documented. I imagine that a
similar mechanism as above is engaged. When bash
# sees "address@hidden" it considers " the beginning of a string, it finds
the 'X' and considers it a string that must be concatenated with
# the first element of the array, and the things go ahead as documented.
4) set -u; set -- A C B; for s in "$@"; do echo "s=${s}"; done
# It prints : "s=A s=B s=C"
# similar things as above happen here with the difference that a zero length
string is concatenated with the first element of the
# array.
5) set -u; set --; for s in "$@"; do echo "s=${s}"; done
# it prints nothing. For me (and I hope that for others) this works
perfectly. But bash does not engage the same mechanisms as above
# because in this case bash does not find a zero length string between " and
$ that is concatenated with the empty expanssion
# and so on, as documented. The manual should clarify that address@hidden and
"address@hidden" (or if bash would support other empty arrays that
# address@hidden and "address@hidden") expand to nothing when the array is
empty.
> Horrible workaround:
>
> Copy to the argument array:
>
> set -- "address@hidden"
>
> Copy from the arguments array:
>
> declare -a A=( "$@" )
>
> Then use "$@" , for i in "$@", etc. everywhere?
>
thank you.
> -----
> I would also like it if bash would provide a way to safely interpolate empty
arrays with set -u. Syntax idea:
> echo "${A[@@]}"
> That way there is no extra mode, which is harder to read IMO.
> Andy
>
Cristi
- Re: [Help-bash] Awkward behavior of empty arrays, Cristian Zoicas, 2017/09/05
- Re: [Help-bash] Awkward behavior of empty arrays, DJ Mills, 2017/09/05
- Re: [Help-bash] Awkward behavior of empty arrays, Andy Chu, 2017/09/05
- Re: [Help-bash] Awkward behavior of empty arrays, Cristian Zoicas, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays,
Cristian Zoicas <=
- Re: [Help-bash] Awkward behavior of empty arrays, Cristian Zoicas, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays, Greg Wooledge, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays, Andy Chu, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays, Chris F.A. Johnson, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays, DJ Mills, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays, Chet Ramey, 2017/09/07
- Re: [Help-bash] Awkward behavior of empty arrays, Andy Chu, 2017/09/07