Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 815
James Brown Avatar asked Nov 14 '14 08:11

James Brown


4 Answers

In bash 4.2 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.

like image 82
chepner Avatar answered Oct 14 '22 11:10

chepner


You can use declare -p to check if a variable has been declared:

declare -p FOO >/dev/null 2>&1 && echo "exists" || echo "nope"

And to check specifically associative array:

[[ "$(declare -p FOO 2>/dev/null)" == "declare -A"* ]] &&
   echo "array exists" || echo "nope"
like image 41
anubhava Avatar answered Oct 14 '22 13:10

anubhava


This is a Community Wiki version of an excellent answer by @user15483624 on a question which is now closed as duplicate. Should that user choose to add their own answer here, this should be deleted in favor of the one with their name on it.


The prior answers on this question should be used only when compatibility with bash 4.x and prior is required. With bash 5.0 and later, an expansion to check variable type is directly available; its use is far more efficient than parsing the output of declare -p, and it avoids some of the unintended side effects of other proposals as well..

The following can be used to test whether a bash variable is an associative array.

[[ ${x@a} = A ]]

${x@a} can be used to test whether it is a variable and an array as well.

$ declare x; echo "${x@a}"

$ declare -a y; echo "${y@a}"
a
$ declare -A z; echo "${z@a}"
A
like image 6
Charles Duffy Avatar answered Oct 14 '22 12:10

Charles Duffy


One of the easiest ways is to the check the size of the array:

size=${#array[@]}
[ "$size" -lt 1 ] && echo "array is empty or undeclared"

You can easily test this on the command line:

$ declare -A ar=( [key1]=val1 [key2]=val2 ); echo "szar: ${#ar[@]}"
szar: 2

This method allow you to test whether the array is declared and empty or undeclared altogether. Both the empty array and undeclared array will return 0 size.

like image 2
David C. Rankin Avatar answered Oct 14 '22 13:10

David C. Rankin