I'm writing a script and I discovered some unexpected behaviour of uninitialized and unset array variables that I do not understand.

First of all, the length:

$ echo ${#notset[@]}
$ uninitialized=
$ echo ${#uninitialized[@]}

Why is the uninitialized length 1? Shouldn't it be zero? Is it because a null variable is considered an array of one null element?

This fact leads to some problems. For example suppose I want to create an array, and insert a certain number of things based on the user command line arguments. I thought I could do something like(+):


if [ some-condition ]

if [ some-condition2 ]
elif [ some-condition3 ]

But this leaves the first slot to null, which I do not like and also breaks some code that I have written(*), and at this point suppose that I want to see if the array contains any element. How should I do it?

[ -z "${myarray[@]}" ]

Raises an error if the array contains more than an element.

[ -z "$myarray" ]

Fails because the first element is null, even if the array is not empty.

So, how should I control that an array is uninitialized?

And could someone explain what exactly happens when dealing with arrays and unset - uninitialized variables?

(+) I know that I could avoid "declaring" the variable and it would work, but this script will be reviewed by a professor, and he does not like variables being defined at random places.

(*) Before trying this thing I was keeping the length of the array in an other variable, and so I did not have problems. But I'd like to avoid defining this auxiliary variables since I know I can obtain the length without them.

  • Note that uninitialized is not uninitialized; its first element is the empty string. foo and ${foo[0]} are nearly interchangeable. – chepner Apr 22 '14 at 18:38

You can see the difference with declare -p:

unset foo
declare -a foo
declare -p foo
# prints declare -a foo='()'
declare -p foo
# prints declare -a foo='([0]="")'

If you want to initialize an empty array, the output of the first declare -p is a good hint on the best way to declare it:

declare -a array='()'

(The declare -a part is probably optional, a simple array=() should work just as well.)

If you want to test if an array has 0 elements, use numeric comparison on ${#array[@]}; don't try to do a test -z on the expansion as won't give the correct result in many cases.

  • I did not know of declare -p. Thank you for solving my doubts. The only thing that is not clear to me is your last sentence. I always used the ${#array[@]} notation, why did you tell me to not use the other one? – Bakuriu Oct 26 '12 at 17:37
  • 1
    @Bakuriu I was just trying to say that to test if an array is empty, it is easier to test if the count provided by ${#array[@]} is 0 than trying to expand the array contents and testing if the resulting string is empty. – jw013 Oct 26 '12 at 17:47

To initialize an empty array, use


To add a value to the array, use

  • Great, I did not know of this syntax. The only thing is that this requires to use declare -a var to avoid having the null at the beginning. – Bakuriu Oct 26 '12 at 17:38
  • 1
    @Bakuriu: Initialize it as array=(). – choroba Oct 26 '12 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.