2014-11-14 10 views
5

Come posso verificare se un array associativo è dichiarato in Bash? Posso provare per una variabile come:Nel test Bash se viene dichiarato un array associativo

[ -z $FOO ] && echo nope 

ma non sembra funzionare per gli array associativi:

$unset FOO 
$declare -A FOO 
$[ -z $FOO ] && echo nope 
nope 
$FOO=([1]=foo) 
$ [ -z $FOO ] && echo nope 
nope 
$ echo ${FOO[@]} 
foo 

EDIT:

Grazie per le vostre risposte, entrambi sembrano per lavorare quindi decido:

$ cat test1.sh 
#!/bin/bash 
for i in {1..100000}; do 
    size=${#array[@]} 
    [ "$size" -lt 1 ] && : 
done 
$ time bash test1.sh #best of five 

real 0m1.377s 
user 0m1.357s 
sys  0m0.020s 

e il altro:

$ cat test2.sh 
#!/bin/bash 

for i in {1..100000}; do 
    declare -p FOO >/dev/null 2>&1 && : 
done 
$ time bash test2.sh #again, the best of five 

real 0m2.214s 
user 0m1.587s 
sys  0m0.617s 

EDIT 2: velocità

Let confrontare la soluzione di Chepner contro i precedenti:

#!/bin/bash 

for i in {1..100000}; do 
    [[ -v FOO[@] ]] && : 
done 
$ time bash test3.sh #again, the best of five 

real 0m0.409s 
user 0m0.383s 
sys  0m0.023s 

Bene che era veloce.

Grazie ancora, ragazzi.

risposta

5

In bash 4.2 o versione successiva, è possibile utilizzare l'opzione -v:

[[ -v FOO[@] ]] && echo "FOO set" 

Si noti che in qualsiasi versione, utilizzando

declare -A FOO 

non effettivamente creare immediatamente un array associativo; imposta semplicemente un attributo sul nome FOO che consente a di assegnarlo al nome come array associativo. L'array stesso non esiste fino al primo incarico.

+0

Finora non sono riuscito a trovare alcun caso in cui "FOO [@]" nel codice precedente possa produrre risultati diversi rispetto a "FOO". Se l'intento fosse anche quello di rilevare che FOO non è un array, non conosco alcuna soluzione che non richieda l'uso di 'declare' (il controllo della dimensione dell'array offerto qui sotto non aiuta). –

+0

Immagino che un bash abbastanza nuovo possa evitare 'declare' usando' $ {FOO @ A} 'per ottenere le stesse informazioni su' FOO'. –

7

È possibile utilizzare declare -p per verificare se è stata dichiarata una variabile:

declare -p FOO >/dev/null 2>&1 && echo "exists" || echo "nope" 

E per controllare gamma specificamente associativa:

[[ "$(declare -p FOO >/dev/null)" == "declare -A"* ]] && echo "array exists" || echo "nope" 
+1

Non è possibile utilizzare declare -p per verificare se una variabile è stata dichiarata se la variabile non è stata impostata. – Jani

+1

@Jani non è sicuro di quello che stai dicendo. La dichiarazione restituirà uno stato di uscita diverso da zero (contrariamente a quanto afferma il comando 'help') se la variabile non è stata impostata. @anubhava sembra avere un refuso nel secondo esempio (dovrebbe essere '2>/dev/null' Penso).In caso contrario, questa sembra essere l'unica risposta funzionante se si desidera rilevare se il nome è stato dichiarato come array associativo. –

+0

@ RonBurk: Grazie per il tuo commento. '>/dev/null 2> & 1' reindirizza sia stdout che stderr a'/dev/null', quindi possiamo lavorare solo sul codice di uscita qui. – anubhava

2

Uno dei modi più semplici è quello il controllare la dimensione di l'array:

size=${#array[@]} 
[ "$size" -lt 1 ] && echo "array is empty or undeclared" 

È possibile testarlo facilmente sulla riga di comando:

$ declare -A ar=([key1]=val1 [key2]=val2); echo "szar: ${#ar[@]}" 
szar: 2 

Questo metodo consente di verificare se la matrice è dichiarata e vuota o non dichiarata del tutto. Sia l'array vuoto che l'array non dichiarato restituiscono la dimensione 0.

Problemi correlati