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[@]}
0
$ uninitialized=
$ echo ${#uninitialized[@]}
1
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(+):
myarray=
if [ some-condition ]
then
myarray[${#myarray[@]}]=some-value
fi
if [ some-condition2 ]
then
myarray[${#myarray[@]}]=some-value2
elif [ some-condition3 ]
then
myarray[${myarray[@]}]=some-value3
myarray[${myarray[@]}]=some-value4
fi
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.
uninitialized
is not uninitialized; its first element is the empty string.foo
and${foo[0]}
are nearly interchangeable.