2016-02-03 23:43:37 +0000, Martijn Dekker: > bash treats an empty array as if it were an unset variable, which seems > very illogical as empty is quite distinct from unset: > > $ myarray=() > $ [[ -v myarray ]] && echo set || echo unset > unset
[[ -v var ]] is for scalar variables (AFAICT). bash like ksh arrays to some extend overload. (as in $var is ${var[0]}). $ bash -c 'a[1]=x; [[ -v a ]]' || echo unset unset $ bash -c 'a[1]=x; [[ -v a[@] ]]' && echo set set ~$ bash -c 'a=(""); [[ -v a[@] ]]' && echo set set In: $ bash -c 'a=(); [[ -v a[@] ]]' || echo unset unset It still returns "unset" as none of the elements are set. You can always check whether the variable is "bound" with declare -p declare -p array >/dev/null 2>&1 && echo set I don't know how one can check whether the variable is /declared/ or not though (when it's not "bound"). > $ set | grep ^myarray= # yet, it's set: > myarray=() > $ set -u > $ for i in "${x[@]}"; do :; done > bash: x[@]: unbound variable > > Note also that the "unbound variable" error is inconsistent with the > behaviour of "$@"; I would have thought that, logically, "$@" and > "${x[@]}" should behave the same way, since arrays are implemented as a > logical extension of the positional parameters concept. Agreed. > zsh and ksh93 can distinguish between empty and unset arrays. [...] In zsh, arrays are a clearly distinct type. You may want to check the archieve, I beleive it's been discussed before. -- Stephane