declare -a A
Erstellen Sie ein leeres Array A
in bash, oder setzt es nur ein Attribut im Fall A
wird später zugeordnet?
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 die erwartete Ausgabe sein?
In Bash 4.3.48(1) erhalte ich bash: A: unbound variable
bei der Abfrage der Anzahl der Elemente nach declare
.
Ich bekomme diesen Fehler auch, wenn ich auf alle Elemente zugreife.
Ich weiß, dass spätere Versionen von Bash das anders behandeln.
Trotzdem würde ich gerne wissen, ob declare
tatsächlich definiert eine Variable (muss leer sein).
Akzeptierte Antwort:
Das hängt davon ab, ob die entsprechende Variable bereits zuvor im aktuellen Gültigkeitsbereich (oberste Ebene, auch bekannt als globale oder aktuelle Funktion) deklariert wurde.
Wenn sie nicht im aktuellen Bereich deklariert wurde (und beachten Sie, dass die Variable im Bereich der obersten Ebene möglicherweise deklariert wurde (und zugewiesen), indem es aus der Umgebung importiert wird), dann deklariert es es (macht es lokal für die Funktion, wenn es sich im Funktionsbereich befindet), weist ihm einen Typ zu, initialisiert es aber nicht, nicht einmal für eine leere Liste (declare -p a
zeigt declare -a a
, nicht declare -a a=()
so, als hätten Sie es mit a=()
deklariert und/oder zugewiesen ).
Wenn es bereits im aktuellen Gültigkeitsbereich deklariert wurde (z. B. weil es im globalen Gültigkeitsbereich als skalare Variable aus der Umgebung importiert wurde), dann declare -a a
würde versuchen, zu konvertieren es in ein Array.
Wenn es zuvor ein Skalar war, wird es zu einem ([0]=value-of-the-variable)
Reihe. Wenn es bereits ein Array war, bleibt es unberührt. Wenn es ein assoziatives Array war, schlägt es mit einem cannot convert associative to indexed array
fehl Fehler.
Beachten Sie, dass declare a
würde ein Array oder einen Hash nicht in einen Skalar konvertieren. bash
wäre sowieso nicht in der Lage, einen Hash/Array in Skalar umzuwandeln. Sie können declare +aA a
verwenden um einen Skalar zu erzwingen (das würde mit einem Fehler fehlschlagen, wenn die Variable zuvor ein Hash/Array im aktuellen Gültigkeitsbereich war).
In Ihrem Fall wurde die Variable wahrscheinlich noch nicht im aktuellen Gültigkeitsbereich deklariert, sodass sie deklariert, aber nicht zugewiesen wurde, was erklärt, warum der Versuch, sie zu erweitern, unter set -u
fehlschlägt .
Diese Unterscheidung zwischen zwei deklariert und zugewiesen /einstellen Zustände einer Variablen ist nicht spezifisch für bash
. In POSIX sh
, können Sie auch export
eine Variable oder machen Sie sie readonly
ohne ihm einen Wert zu geben.
$ sh -uc 'unset -v var; readonly var; : "$var"'
sh: 1: var: parameter not set
Beachten Sie, dass unset
setzt die Variable sowohl zurück als auch undeklariert sie. In bash
, mksh
und yash
es kann die Variable aus einem äußeren Gültigkeitsbereich wiederherstellen.
In zsh
, außer in sh
Emulation mit typeset
on einer Variablen deklariert und setzt sie auf einen leeren Wert, wenn sie noch nicht gesetzt war oder gesetzt wurde, aber von einem anderen Typ (Skalar vs. Array vs. assoziatives Array).