On Mon, May 22, 2023 at 09:27:17AM +1000, Martin D Kealey wrote: > I just realised I expressed an opinion about associative arrays while the > original post was about indexed arrays. >
I simply reported that, specifically in arithmetic contexts, when using a variable (not as the lhs of an = assignment), bash only checks that the variable name before "[" is bound to decide whether to trigger nounset or not: $ set -u $ echo "$(( a[0] ))" # correct, a is not set bash: a: unbound variable $ declare b $ echo "$(( b[0] ))" # correct, b is declared, but not set bash: b: unbound variable $ c=() $ echo "$(( c[0] ))" # wrong, it is supposed to error, c[0] is not set 0 $ echo "$(( c[1] ))" # wrong, it is supposed to error, c[1] is not set 0 $ d=11 $ echo "$(( d[0] ))" # correct, d[0] is set 11 $ echo "$(( d[1] ))" # wrong, it is supposed to error, d[1] is not set 0 $ e=([1]= ) $ echo "$(( e[1] ))" # correct, e[1] is set 0 If the variable has a subscript, it is supposed to also check that the array slot is set, and trigger nounset if it is not. If you run the same commands I marked as wrong above with regular non-unset-immune parameter expansions instead of arithmetic expansions, you will see that nounset is triggered if z is set, but the specific index is not. $ set -u $ unset -v z $ echo "${z[0]}" bash: z[0]: unbound variable $ echo "${z[10*RANDOM+1]}" bash: z[10*RANDOM+1]: unbound variable $ z=() # even if z is set, it still trigger nounset $ echo "${z[0]}" bash: z[0]: unbound variable $ echo "${z[10*RANDOM+1]}" bash: z[10*RANDOM+1]: unbound variable $ d=11 $ echo "${d[1]}" bash: d[1]: unbound variable I think this behaviour is unintented and only happens because the code I linked in the original post is forgetting to check that the array slot is set after expanding variables with a subscript, so it doesn't issue the error. This has nothing to do specifically with associative arrays, though they are also affected by the problem. And it also has nothing to do with [*] and [@] having special treatment when used with nounset to follow the behaviour of $* and $@ in POSIX sh. I am not really proposing a major change to the behaviour of nounset, I am only pointing out the incorrect bash behaviour for that case. emanuele6