J'ai une boucle sur les noms de variables et je dois vérifier si une variable désignée par ce nom est un tableau ou non. J'ai essayé de chercher sur Google mais je n'ai rien trouvé. De l'aide?
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 peut être votre ami :
declare -p variable-name 2> /dev/null | grep -q '^declare \-a'
Pour éviter un appel à grep, vous pouvez utiliser:
if [[ "$(declare -p variable_name)" =~ "declare -a" ]]; then
echo array
else
echo no array
fi
Depuis bash 4.3, ce n’est plus aussi simple que cela.
Avec "declare -n", vous pouvez ajouter une référence à une autre variable et le faire encore et encore. Comme si ce n'était pas assez compliqué, avec "declare -p", vous n'obtenez pas le type ou la variable d'origine.
Exemple:
$ 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"
Par conséquent, vous devez parcourir toutes les références. En bash seulement cela ressemblerait à ceci:
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
}
Avec l'exemple ci-dessus:
$ vartype newtest
ARRAY
Pour vérifier le tableau, vous pouvez modifier le code ou l'utiliser avec grep:
vartype $varname | grep -q "ARRAY"
J'ai commencé avec Reuben excellente réponse ci-dessus. J'ai implémenté quelques-uns des commentaires et certaines de mes propres améliorations.
#!/bin/bash
array_test() {
# no argument passed
[[ $# -ne 1 ]] && echo 'Supply a variable name as an argument'>&2 && return 2
var=$1
# use a variable to avoid having to escape spaces
regex="^declare -[aA] ${var}(=|$)"
[[ $(declare -p "$var" 2> /dev/null) =~ $regex ]] && return 0
}
Maintenant je peux faire ça:
foo=(lorem ipsum dolor)
bar="declare -a tricky"
declare -A baz
array_test foo && echo "it's an array"
array_test bar && echo "it's an array"
# properly detects empty arrays
array_test baz && echo "it's an array"
# won't throw errors on undeclared variables
array_test foobarbaz && echo "it's an 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" ]]
}