Ich habe eine Schleife über Variablennamen und muss überprüfen, ob eine Variable, auf die dieser Name verweist, ein Array ist oder nicht. Ich versuchte es zu googeln, konnte aber nichts finden. Irgendeine Hilfe?
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 kann sein dein Freund :
declare -p variable-name 2> /dev/null | grep -q '^declare \-a'
Um einen Anruf bei grep zu vermeiden, können Sie Folgendes verwenden:
if [[ "$(declare -p variable_name)" =~ "declare -a" ]]; then
echo array
else
echo no array
fi
Seit Bash 4.3 ist das nicht mehr so einfach.
Mit "declare -n" können Sie einen Verweis auf eine andere Variable hinzufügen und dies immer wieder tun. Als wäre dies nicht kompliziert genug, erhalten Sie mit "declare -p" weder den Typ noch die ursprüngliche Variable.
Beispiel:
$ 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"
Deshalb müssen Sie alle Referenzen durchlaufen. In bash-only würde das so aussehen:
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
}
Mit dem obigen Beispiel:
$ vartype newtest
ARRAY
Um nach einem Array zu suchen, können Sie den Code ändern oder ihn mit grep verwenden:
vartype $varname | grep -q "ARRAY"
Ich habe mit Reubens guter Antwort oben angefangen. Ich habe ein paar Kommentare und einige meiner eigenen Verbesserungen umgesetzt und kam dazu:
#!/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
}
Jetzt kann ich das machen:
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" ]]
}