In bash, the conditional expression with the unary test -v myvariable
tests wether the variable myvariable
has been set. Note that myvariable
should not be expanded by prefixing it with a dollar, so not $myvariable
.
Now I find that for array elements the conditional expression -v myarray[index]
works well too, without the full expansion syntax ${myarray[$index]}
. Try this:
myarray[2]=myvalue
for i in 1 2 3
do
[ -v myarray\[i] ] && echo element $i is set
done
(note the escape \[
to prevent globbing, as alternative to using quotes)
gives the desired output:
element 2 is set
Question Is this behaviour safe to use aka is this documented behaviour?
Addendum After reading the answer https://unix.stackexchange.com/a/677920/376817 of Stéphane Chazelas, I expanded my example:
myarray[1]=val myarray[2]=val myarray[3]=val myarray[4]=val myarray[5]=val myarray[6]="" myarray[2]=""
unset myarray[3] myarray[4] myarray[5]
touch myarray4 myarrayi
myarray4=val myarrayi=val
then
for i in {0..7}; do [ -v myarray\[i] ] && echo element $i is set; done
gives
element 1 is set
element 2 is set
element 6 is set
Without quoting or escaping the index expression [i]
:
for i in {0..7}; do [ -v myarray[i] ] && echo element $i is set; done
gives
element 0 is set
element 1 is set
element 2 is set
element 3 is set
element 4 is set
element 5 is set
element 6 is set
element 7 is set
The same with the variable myarrayi
unset :
unset myarrayi
for i in {0..7}; do [ -v myarray[i] ] && echo element $i is set; done
gives
%nothing%
And finally with expansion of the index as $i
(still without quoting or escaping the bracket) :
for i in {0..7}; do [ -v myarray[$i] ] && echo element $i is set; done
it gives
element 1 is set
element 2 is set
element 4 is set
because
ls -l myarray*
shows
-rw-rw-r-- 1 me us 0 nov 17 15:37 myarray4
-rw-rw-r-- 1 me us 0 nov 17 15:37 myarrayi