Erstellt declare -a A
ein leeres Array A
in Bash oder legt es nur ein Attribut fest, falls 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 die erwartete Ausgabe sein?
In Bash 4.3.48 (1) bekomme ich bash: A: unbound variable
beim Abfragen die Anzahl der Elemente danach declare
. Ich erhalte diesen Fehler auch beim Zugriff auf alle Elemente. Ich weiß, dass spätere Versionen von Bash dies anders behandeln. Trotzdem möchte ich wissen, ob declare
tatsächlich eine Variable definiert ist (um leer zu sein).
declare -a P; Q=()
, danndeclare -p P Q
oderset | grep -w '^[PQ]'
zu bash Vorstellung von Ihren Variablen zu zeigen. Befriedigt Sie das oder suchen Sie etwas Tieferes?Antworten:
Dies hängt davon ab, ob die entsprechende Variable bereits zuvor im aktuellen Bereich deklariert wurde (oberste Ebene, auch bekannt als globale oder aktuelle Funktion).
Wenn es im aktuellen Bereich nicht deklariert wurde (und beachten Sie, dass die Variable im Bereich der obersten Ebene möglicherweise durch Importieren aus der Umgebung deklariert (und zugewiesen) wurde), deklariert sie es (macht es lokal für die Funktion Wenn Sie sich im Funktionsumfang befinden, weisen Sie ihm einen Typ zu, initialisieren ihn jedoch nicht, auch nicht einer leeren Liste (wird
declare -p a
angezeigtdeclare -a a
, nicht so,declare -a a=()
als hätten Sie ihn deklariert und / oder zugewiesena=()
).Wenn es bereits im aktuellen Bereich deklariert wurde (z. B. weil es im globalen Bereich als skalare Variable aus der Umgebung importiert wurde),
declare -a a
würde versucht , es in ein Array zu konvertieren .Wenn es zuvor ein Skalar war, wird es zu einem
([0]=value-of-the-variable)
Array. Wenn es bereits ein Array war, bleibt es unberührt. Wenn es sich um ein assoziatives Array handelt, schlägt dies mit einemcannot convert associative to indexed array
Fehler fehl .Beachten Sie, dass
declare a
ein Array oder Hash nicht in einen Skalar konvertiert wird.bash
wäre sowieso nicht in der Lage, einen Hash / Array in Skalar zu konvertieren. Sie könnendeclare +aA a
einen Skalar erzwingen (dies würde mit einem Fehler fehlschlagen, wenn die Variable zuvor ein Hash / Array im aktuellen Bereich war).In Ihrem Fall wurde die Variable wahrscheinlich noch nicht im aktuellen Bereich deklariert, sodass sie deklariert, aber nicht zugewiesen wurde. Dies erklärt, warum der Versuch, sie zu erweitern, unter fehlschlägt
set -u
.Diese Unterscheidung zwischen zwei deklarierten und zugewiesenen / gesetzten Zuständen einer Variablen ist nicht spezifisch für
bash
. In POSIXsh
können Sie auchexport
eine Variable erstellen oder erstellen,readonly
ohne einen Wert anzugeben.Beachten Sie, dass
unset
die Variable sowohl deaktiviert als auch nicht deklariert wird. Inbash
,mksh
undyash
es kann die Variable aus einem äußeren Bereich wiederherstellen.In
zsh
, außer in dersh
Emulation,typeset
deklariert die Verwendung einer Variablen und setzt sie auf einen leeren Wert, wenn sie nicht bereits festgelegt wurde oder festgelegt wurde, sondern von einem anderen Typ (Skalar vs. Array vs. assoziatives Array).quelle
A
vorher nicht deklariert wurdedeclare -a A
,A
immer noch kein Array ist (weil es sonst ein leeres Array mit 0 Elementen wäre), sondern undefiniert. Was ist der Zweck,declare -a
wenn ich Arrays durch Zuweisung (A=()
,A[0]=...
) erstellen kann ?declare -a
/declare -A
dienen nur zur Unterscheidung, wenn Sie das Array mit dem folgenden Namen als indiziertes oder assoziatives Array verwenden möchten. Keiner von ihnen setzt / initialisiert Wertea=foo
tun würde ,a[0]=foo
unddeclare -p a
es als ein Array zeigen würde. Aber die Hauptverwendung vondeclare
in in Funktion, um die Funktion lokal für die Funktion zu machen. Es ist wie fürexport
, es weist es nicht zu, sondern merkt sich dasexport
Attribut, falls die Variable später zugewiesen wird.