bashassociative-array

In Bash test if associative array is declared


How can I test if an associative array is declared in Bash? I can test for a variable like:

[ -z $FOO ] && echo nope

but I doesn't seem to work for associative arrays:

$ unset FOO
$ declare -A FOO
$ [ -z $FOO ] && echo nope
nope
$ FOO=([1]=foo)
$ [ -z $FOO ] && echo nope
nope
$ echo ${FOO[@]}
foo

EDIT:

Thank you for your answers, both seem to work so I let the speed decide:

$ cat test1.sh
#!/bin/bash
for i in {1..100000}; do
    size=${#array[@]}
    [ "$size" -lt 1 ] && :
done
$ time bash test1.sh #best of five

real    0m1.377s
user    0m1.357s
sys     0m0.020s

and the other:

$ cat test2.sh
#!/bin/bash

for i in {1..100000}; do
    declare -p FOO >/dev/null 2>&1 && :
done
$ time bash test2.sh #again, the best of five

real    0m2.214s
user    0m1.587s
sys     0m0.617s

EDIT 2:

Let's speed compare Chepner's solution against the previous ones:

#!/bin/bash

for i in {1..100000}; do
    [[ -v FOO[@] ]] && :
done
$ time bash test3.sh #again, the best of five

real    0m0.409s
user    0m0.383s
sys     0m0.023s

Well that was fast.

Thanks again, guys.


Solution

  • In bash 4.3 or later, you can use the -v option:

    [[ -v FOO[@] ]] && echo "FOO set"
    

    Note that in any version, using

    declare -A FOO
    

    doesn't actually create an associative array immediately; it just sets an attribute on the name FOO which allows you to assign to the name as an associative array. The array itself doesn't exist until the first assignment.