Erstellt `declare -a A` in Bash ein leeres Array `A`?

Erstellt `declare -a A` in Bash ein leeres Array `A`?

Erstellt es in Bash declare -a Aein leeres Array Aoder legt es einfach ein Attribut für den Fall fest, dass Aes später zugewiesen wird?

Betrachten Sie diesen Code:

set -u
declare -a A
echo ${#A[*]}
echo ${A[*]}
A=()
echo ${#A[*]}
echo ${A[*]}
A=(1 2)
echo ${#A[*]}
echo ${A[*]}

Was sollte das erwartete Ergebnis sein?

In Bash 4.3.48(1) erhalte ich bash: A: unbound variablebeim Abfragen der Anzahl der Elemente nach declare. Ich erhalte diesen Fehler auch beim Zugriff auf alle Elemente. Ich weiß, dass spätere Versionen von Bash dies anders behandeln. Trotzdem würde ich gerne wissen, ob declaretatsächlichdefinierteine Variable (die leer sein muss).

Antwort1

Dies hängt davon ab, ob die entsprechende Variable zuvor bereits im aktuellen Gültigkeitsbereich (oberste Ebene, d. h. global oder aktuelle Funktion) deklariert wurde.

Wenn sie im aktuellen Gültigkeitsbereich nicht deklariert wurde (und beachten Sie, dass die Variable im Gültigkeitsbereich der obersten Ebene möglicherweiseerklärt(und zugewiesen), indem es aus der Umgebung importiert wird), dann deklariert es es (macht es lokal für die Funktion, wenn es sich im Funktionsumfang befindet), weist ihm einen Typ zu, initialisiert es aber nicht, nicht einmal für eine leere Liste ( declare -p azeigt an declare -a a, nicht declare -a a=()so, wie es der Fall wäre, wenn Sie es mit deklariert und/oder zugewiesen hätten a=()).

Wenn es bereits im aktuellen Gültigkeitsbereich deklariert wurde (zum Beispiel weil es als Skalarvariable aus der Umgebung importiert wurde, als es sich im globalen Gültigkeitsbereich befand), declare -a awürde dann versucht,Konvertierenes in ein Array.

Wenn es zuvor ein Skalar war, wird es zu einem ([0]=value-of-the-variable)Array. Wenn es bereits ein Array war, bleibt es unverändert. Wenn es ein assoziatives Array war, schlägt es mit einem cannot convert associative to indexed arrayFehler fehl.

Beachten Sie, dass declare aein Array oder Hash nicht in einen Skalar konvertiert wird. bashEin Hash/Array kann ohnehin nicht in einen Skalar konvertiert werden. Sie können verwenden, declare +aA aum einen Skalar zu erzwingen (das würde mit einem Fehler fehlschlagen, wenn die Variable zuvor ein Hash/Array im aktuellen Bereich war).

In Ihrem Fall war die Variable im aktuellen Bereich wahrscheinlich noch nicht deklariert, sodass sie zwar deklariert, aber nicht zugewiesen wurde. Dies erklärt, warum der Versuch, sie zu erweitern, unter fehlschlägt set -u.

Diese Unterscheidung zwischen zweierklärtUndzugewiesen/SatzZustände einer Variablen sind nicht spezifisch bash. In POSIX shkönnen Sie auch exporteine Variable erstellen oder löschen, readonlyohne ihr einen Wert zuzuweisen.

$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set

Beachten Sie, dass unsetsowohl die Variable aufgehoben als auch deklariert wird. In bashkann mkshdie yashVariable aus einem äußeren Bereich wiederhergestellt werden.

In wird zsh, außer bei shder Emulation, durch die Verwendung typesetvon auf eine Variable diese deklariert und auf einen leeren Wert gesetzt, wenn sie nicht bereits gesetzt war oder gesetzt war, aber von einem anderen Typ (Skalar vs. Array vs. assoziatives Array).

verwandte Informationen