Ich schreibe ein Skript und habe ein unerwartetes Verhalten von nicht initialisierten und nicht gesetzten Array-Variablen entdeckt, das ich nicht verstehe.
Zuallererst die Länge:
$ echo ${#notset[@]}
0
$ uninitialized=
$ echo ${#uninitialized[@]}
1
Warum ist die uninitialized
Länge 1? Sollte es nicht Null sein? Liegt es daran, dass eine Nullvariable als Array eines Nullelements betrachtet wird?
Diese Tatsache führt zu einigen Problemen. Angenommen, ich möchte ein Array erstellen und eine bestimmte Anzahl von Dingen basierend auf den Benutzerbefehlszeilenargumenten einfügen. Ich dachte, ich könnte so etwas wie (+) machen :
myarray=
if [ some-condition ]
then
myarray[${#myarray[@]}]=some-value
fi
if [ some-condition2 ]
then
myarray[${#myarray[@]}]=some-value2
elif [ some-condition3 ]
then
myarray[${myarray[@]}]=some-value3
myarray[${myarray[@]}]=some-value4
fi
Dies lässt jedoch den ersten Slot auf null, was mir nicht gefällt, und bricht auch einen von mir geschriebenen Code (*) . An dieser Stelle möchte ich sehen, ob das Array ein Element enthält. Wie soll ich das machen
[ -z "${myarray[@]}" ]
Löst einen Fehler aus, wenn das Array mehr als ein Element enthält.
[ -z "$myarray" ]
Schlägt fehl, weil das erste Element null ist, auch wenn das Array nicht leer ist.
Wie soll ich also steuern, dass ein Array nicht initialisiert ist?
Und könnte jemand erklären, was genau passiert, wenn es um Arrays und nicht festgelegte - nicht initialisierte Variablen geht?
(+) Ich weiß, dass ich es vermeiden könnte, die Variable zu "deklarieren", und es würde funktionieren, aber dieses Skript wird von einem Professor überprüft, und er mag es nicht, wenn Variablen an zufälligen Stellen definiert werden.
(*) Bevor ich dieses Ding ausprobierte, behielt ich die Länge des Arrays in einer anderen Variablen bei und hatte daher keine Probleme. Ich möchte jedoch vermeiden, diese Hilfsvariablen zu definieren, da ich weiß, dass ich die Länge ohne sie erhalten kann.
uninitialized
ist nicht nicht initialisiert; Das erste Element ist die leere Zeichenfolge.foo
und${foo[0]}
sind fast austauschbar.Antworten:
Sie können den Unterschied sehen mit
declare -p
:Wenn Sie ein leeres Array initialisieren möchten, ist die Ausgabe des ersten
declare -p
ein guter Hinweis darauf, wie Sie es am besten deklarieren können:(Das
declare -a
Teil ist wahrscheinlich optional, ein einfachesarray=()
sollte genauso gut funktionieren.)Wenn Sie testen möchten, ob ein Array 0 Elemente enthält, verwenden Sie den numerischen Vergleich für
${#array[@]}
. Versuchen Sie nicht, einetest -z
Erweiterung durchzuführen, da dies in vielen Fällen nicht zum richtigen Ergebnis führt.quelle
declare -p
. Vielen Dank, dass Sie meine Zweifel gelöst haben. Das einzige, was mir nicht klar ist, ist dein letzter Satz. Ich habe immer die${#array[@]}
Notation verwendet. Warum hast du mir gesagt, dass ich die andere nicht verwenden soll?${#array[@]}
0 bereitgestellte Anzahl 0 ist, als zu versuchen, den Array-Inhalt zu erweitern und zu testen, ob die resultierende Zeichenfolge leer ist.Verwenden Sie zum Initialisieren eines leeren Arrays
Verwenden Sie, um dem Array einen Wert hinzuzufügen
quelle
declare -a var
zu vermeiden, dass die Null am Anfang steht.array=()
.