Warum funktioniert diese Syntax nicht zum Deklarieren eines assoziativen Arrays

Warum funktioniert diese Syntax nicht zum Deklarieren eines assoziativen Arrays

Kann ich eine Variable innerhalb der ()-Syntax verwenden?

#!/bin/bash
declare -A c
declare -A b
a="[a]=0 [b]=1 [c]=2 [d]=3"
b=($a) # or b=($(echo "$a"))
echo "***********${b[@]}*********"  #********************

c=([a]=0 [b]=1 [c]=2 [d]=3)
echo "---------${c[@]}----------"  #---------0 1 2 3----------

Antwort1

Derzeit ist es (soweit ich weiß) nicht möglich, in Bash Zeichenfolgen zu verwenden und damit assoziative Arrays zu erstellen. Daher müssen Sie sie vor der Verwendung der evalAnweisung „auswerten“.

Wenn ich Ihr Beispiel ausführe, erhalte ich bei Verwendung von Bash Version 4.1.7 Folgendes:

$ ./arr.bash 
./arr.bash: line 5: b: [a]=0: must use subscript when assigning associative array
./arr.bash: line 5: b: [b]=1: must use subscript when assigning associative array
./arr.bash: line 5: b: [c]=2: must use subscript when assigning associative array
./arr.bash: line 5: b: [d]=3: must use subscript when assigning associative array

Das Ändern der Zeile wie folgt funktioniert:

eval "b=($a)" # or b=($(echo "$a"))

Beim erneuten Ausführen erhalten Sie nun die erwarteten Ergebnisse:

$ ./arr.bash 
***********0 1 2 3*********
---------0 1 2 3----------

Erläuterung

Ich habe dieses SO-Q&A mit dem Titel gefunden:Bash: Wie weist man einem assoziativen Array einen anderen Variablennamen zu (z. B. durch Umbenennen der Variable)?, das eine Methode veranschaulicht, mit der dies erreicht werden kann declare, aber es zeigt, wie unlesbar diese Methode tatsächlich ist und daher wahrscheinlich nicht verwendet werden sollte.

# declare associative array
declare -A assoc_array=(["key1"]="value1" ["key2"]="value2")
# convert associative array to string
assoc_array_string=$(declare -p assoc_array)
# create new associative array from string
eval "declare -A new_assoc_array="${assoc_array_string#*=}
# show array definition
declare -p new_assoc_array

Diese Methode zeigt, wie $assoc_arrayin einen String konvertiert und dann wieder in ein assoziatives Array zurückkonvertiert wird. $new_assoc_arrayAber auch diese Methode kann die Notwendigkeit der Verwendung nicht umgehen eval. Dies ist ein schwer verständlicher Codeausschnitt und zeigt, warum er wirklich vermieden werden sollte.

Antwort2

Du brauchst

eval "b=($a)"

evalwertet sein Argument nach der Parametererweiterung als Shell-Befehl aus. Verwenden Sie es jedoch mit Vorsicht. Stellen Sie sicher, dass es $anicht durch Benutzereingaben festgelegt wird, da dies zu allen möglichen Problemen führen kann.

verwandte Informationen