1

Why is an empty key in a bash array always the zero key element?

Try

empty_key=

h[0]=0
h[1]=1
h[2]=2

echo ${h[$empty_key]}

Result

0

Could you please explain, why this behavior is correct?

In my understanding it should not be different to

not_existing_key=5 
echo ${h[$not_existing_key]}

where the result is just empty.

This is important to understand, if one uses the result for a loop, like in

for element in ${h[$key]};do
  ...
done

where the empty_key leads to a cycle, but NOT the not_existing_key.

To avoid this behavior it is obviously not to start an array with index 0

OR

replace an empty key by any key value not assigned (what seems to be boring).

Again my question: why is this behavior correct?

EDIT: My question should be understood as why is this behavior the prefered one in the bash world and not an empty result as with a non-existing key value?

4
  • @anubhava: Sorry, your statement is not true. A not_existing_key gives you just an empty result, not the 0-key element Commented Nov 28, 2019 at 15:59
  • Please, read again the question text where the not_existing_key has a non-empty value. Fue Commented Nov 28, 2019 at 17:57
  • ${h[$not_existing_key]} gives "" whereas $h[] gives 0[] Commented Nov 28, 2019 at 18:07
  • Okay, but it does not make your first statement true and this should be clear to the next reader. Thx Commented Nov 28, 2019 at 18:10

1 Answer 1

7

When accessing an array element, [] constitutes an arithmetic context. This has a few consequences:

  • no need for $ to dereference variables:

    $ arr=(a b c)
    $ idx=1
    $ echo ${arr[idx]}
    b
    
  • arithmetic operations are evaluated:

    $ echo ${arr[idx+idx]}
    c
    
  • variable names are dereferenced in "chains" (evaluated as an arithmetic expression in the manual):

    $ idx=2
    $ idxref=idx
    $ echo ${arr[idxref]}
    c
    
  • names of null or unset variables are evaluated to 0 when used without parameter expansion syntax:

    $ notset=
    $ echo ${arr[notset]}
    a
    
  • and finally (your question), a null value evaluates to 0:

    $ notset=
    $ echo {$arr[$notset]}
    a
    

Manual quotes:

  • Arrays:

    Indexed arrays are referenced using integers (including arithmetic expressions (see Shell Arithmetic)) [...]

  • Shell Arithmetic:

    Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax. [...] A null value evaluates to 0.

Sign up to request clarification or add additional context in comments.

11 Comments

(your question), names of unset - hm... not really his question, he does ${h[$not_existing_key]} not ${h[not_existing_key]}. Or is it the same? I think this has to do with echo $[] printing 0. required for dereferencing - but doesn't the variable expansion inside the [ braces happens before variable expansion of ${ braces? So when ${ expansion happens it only sees empty [] braces, because $not_existing_key expands to nothing first?
@KamilCuk It's the same because of the first effect, no $ required for dereferencing.
»variable names are dereferenced in "chains"«. It even goes beyond that: Whole expressions are evaluated recursively. Example: a=1; b=a+2; c=b+3; echo $((c)) will print the result of 1+2+3, that is, 6.
@KamilCuk I think "referencing without subscript" means $arr, which is the same as ${arr[0]}, though.
@onemorequestion "Why is this the way Bash does it" might only be answered by Chet Ramey.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.