People, are we forgetting that this is supposed to work in a function, by passing the name of a variable?
i.e. it has to look like this: a= b=x is_defined a -> yes is_defined b -> yes is_defined c -> no The 'length of array' expansion doesn't work when you're given a name. So far, the best I could think of is 'is_defined3': dualbus@hp ~ % ./test2 function a b c A B C D AA BB CC DD is_defined1 1 0 1 1 0 1 0 1 0 1 1 is_defined2 1 0 1 1 0 1 0 1 0 1 1 is_defined3 0 0 1 0 0 1 0 0 0 1 0 note: 0 : yes, 1 : no Greg, close your eyes, you will *not* like this :) dualbus@hp ~ % cat ./test2 #!/bin/bash # note for is_defined[12]: if you expand an associative array with "${aa[@]}"; # it will expand to its values. is_defined1() { local an="$1[@]" local -a a=("${!an}") [[ ${!1+x} = x ]] || [[ "${#a}" -gt 0 ]] } is_defined2() { local an="$1[@]" local -a a=("${!an}") [[ -v "$1" ]] || [[ "${#a}" -gt 0 ]] } is_defined3() { { declare -p -- "$1" && ! declare -fp -- "$1"; } 2>/dev/null >&2 } a= b=x A=() B=(X) D=('') declare -A AA=() declare -A BB=(['x']=x) declare -A DD=(['x']=) declare -A is_defined{1..3} vars=(a b c A B C D AA BB CC DD) for var in "${vars[@]}"; do is_defined1 "$var"; is_defined1["$var"]=$? is_defined2 "$var"; is_defined2["$var"]=$? is_defined3 "$var"; is_defined3["$var"]=$? done printf '%s' function for var in "${vars[@]}"; do printf '\t%s' "$var" done; printf \\n for result in is_defined{1..3}; do printf '%s' "$result" for var in "${vars[@]}"; do element="$result[\"$var\"]" printf '\t%s' "${!element}" done; printf \\n done