
Erstellt es in Bash declare -a A
ein leeres Array A
oder legt es einfach ein Attribut für den Fall fest, dass A
es 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 variable
beim 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 declare
tatsä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 a
zeigt 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 a
wü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 array
Fehler fehl.
Beachten Sie, dass declare a
ein Array oder Hash nicht in einen Skalar konvertiert wird. bash
Ein Hash/Array kann ohnehin nicht in einen Skalar konvertiert werden. Sie können verwenden, declare +aA a
um 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 sh
können Sie auch export
eine Variable erstellen oder löschen, readonly
ohne ihr einen Wert zuzuweisen.
$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set
Beachten Sie, dass unset
sowohl die Variable aufgehoben als auch deklariert wird. In bash
kann mksh
die yash
Variable aus einem äußeren Bereich wiederhergestellt werden.
In wird zsh
, außer bei sh
der Emulation, durch die Verwendung typeset
von 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).