Ответ 1
Google может быть ваш друг:
declare -p variable-name 2> /dev/null | grep -q '^declare \-a'
У меня есть цикл над именами переменных, и мне нужно проверить, является ли переменная, на которую указывает это имя, массив или нет. Я попытался сделать это, но ничего не нашел. Любая помощь?
for varname in AA BB CC; do
local val
if [ "$varname" is array ]; then # how can I perform this test?
echo do something with an array
else
echo do something with a "'normal'" variable
fi
done
Google может быть ваш друг:
declare -p variable-name 2> /dev/null | grep -q '^declare \-a'
Чтобы избежать вызова grep, вы можете использовать:
if [[ "$(declare -p variable_name)" =~ "declare -a" ]]; then
echo array
else
echo no array
fi
Так как bash 4.3, это не так просто.
С помощью "declare -n" вы можете добавить ссылку на другую переменную, и вы можете делать это снова и снова. Как будто это было недостаточно сложно, с "declare -p", вы не получаете тип или исходную переменную.
Пример:
$ declare -a test=( a b c d e)
$ declare -n mytest=test
$ declare -n newtest=mytest
$ declare -p newtest
declare -n newtest="mytest"
$ declare -p mytest
declare -n mytest="test"
Поэтому вам нужно пройти все ссылки. В bash - только это будет выглядеть так:
vartype() {
local var=$( declare -p $1 )
local reg='^declare -n [^=]+=\"([^\"]+)\"$'
while [[ $var =~ $reg ]]; do
var=$( declare -p ${BASH_REMATCH[1]} )
done
case "${var#declare -}" in
a*)
echo "ARRAY"
;;
A*)
echo "HASH"
;;
i*)
echo "INT"
;;
x*)
echo "EXPORT"
;;
*)
echo "OTHER"
;;
esac
}
В приведенном выше примере:
$ vartype newtest
ARRAY
Чтобы проверить массив, вы можете изменить код или использовать его с помощью grep:
vartype $varname | grep -q "ARRAY"
is_array() {
local variable_name=$1
[[ "$(declare -p $variable_name)" =~ "declare -a" ]]
}
is_array BASH_VERSINFO && echo BASH_VERSINFO is an array
is_array() {
local variable_name=$1
[[ "$(declare -p $variable_name 2>/dev/null)" =~ "declare -a" ]]
}