Чтобы проверить переменную var, с
b=("${!var[@]}")
c="${#b[@]}"
Можно проверить, есть ли более одного индекса массива:
[[ $c > 1 ]] && echo "Var is an array"
Если первое значение индекса не равно нулю:
[[ ${b[0]} -eq 0 ]] && echo "Var is an array" ## should be 1 for zsh.
Единственная сложная путаница - когда есть только одно значение индекса и это значение равно нулю (или единице).
Для этого условия можно использовать побочный эффект попытки удалить элемент массива из переменной, которая не является массивом:
**bash** reports an error with unset var[0]
bash: unset: var: not an array variable
**zsh** also reports an error with $ var[1]=()
attempt to assign array value to non-array
Это правильно работает для bash:
# Test if the value at index 0 could be unset.
# If it fails, the variable is not an array.
( unset "var[0]" 2>/dev/null; ) && echo "var is an array."
Для zsh индекс должен быть равен 1 (если только не активен совместимый режим).
Под-оболочка нужна, чтобы избежать побочного эффекта стирания индекса 0 переменной var.
Я не нашел способа заставить это работать в ksh.
Эта функция работает только в bash4.2+
getVarType(){
varname=$1;
case "$(typeset -p "$varname")" in
"declare -a"*|"typeset -a"*) echo array; ;;
"declare -A"*|"typeset -A"*) echo hash; ;;
"declare -- "*|"typeset "$varname*| $varname=*) echo scalar; ;;
esac;
}
var=( foo bar ); getVarType var
Эта функция также работает только в bash4.2+
{ typeset -p var | grep -qP '(declare|typeset) -a'; } && echo "var is an array"
Примечание: Это даст ложные срабатывания, если var содержит проверенные строки.