Das Grundproblem hierbei ist, dass die Bash-Entwickler, die Arrays entworfen / implementiert haben, das Hündchen wirklich durcheinander gebracht haben. Sie entschieden, dass dies ${array}
nur eine kurze Hand war ${array[0]}
, was ein schlimmer Fehler war. Besonders wenn Sie bedenken, dass dies ${array[0]}
keine Bedeutung hat und als leere Zeichenfolge ausgewertet wird, wenn der Array-Typ assoziativ ist.
Das Zuweisen eines Arrays erfolgt in der Form, array=(value1 ... valueN)
in der value die Syntax hat [subscript]=string
, wodurch ein Wert direkt einem bestimmten Index im Array zugewiesen wird. Dies macht es so, dass es zwei Arten von Arrays geben kann, numerisch indiziert und Hash-indiziert (im Bash-Sprachgebrauch assoziative Arrays genannt). Es macht es auch so, dass Sie spärliche numerisch indizierte Arrays erstellen können. Das Weglassen des [subscript]=
Teils ist eine kurze Hand für ein numerisch indiziertes Array, beginnend mit dem Ordnungsindex 0 und inkrementierend mit jedem neuen Wert in der Zuweisungsanweisung.
Daher ${array}
sollte auf das gesamte Array, Indizes und alle ausgewertet werden . Es sollte umgekehrt zur Zuweisungsanweisung ausgewertet werden. Jeder CS-Major im dritten Jahr sollte das wissen. In diesem Fall würde dieser Code genau so funktionieren, wie Sie es erwarten würden:
declare -A foo bar
foo=${bar}
Dann würde das Übergeben von Arrays nach Wert an Funktionen und das Zuweisen eines Arrays zu einem anderen funktionieren, wie es der Rest der Shell-Syntax vorschreibt. Da sie dies jedoch nicht richtig gemacht haben, =
funktioniert der Zuweisungsoperator nicht für Arrays, und Arrays können nicht als Wert an Funktionen oder Subshells übergeben oder allgemein ausgegeben werden ( echo ${array}
), ohne dass Code zum Durchkauen verwendet wird .
Wenn es also richtig gemacht worden wäre, würde das folgende Beispiel zeigen, wie die Nützlichkeit von Arrays in Bash wesentlich besser sein könnte:
simple=(first=one second=2 third=3)
echo ${simple}
Die resultierende Ausgabe sollte sein:
(first=one second=2 third=3)
Dann könnten Arrays den Zuweisungsoperator verwenden und als Wert an Funktionen und sogar andere Shell-Skripte übergeben werden. Einfach durch Ausgabe in eine Datei zu speichern und einfach aus einer Datei in ein Skript zu laden.
declare -A foo
read foo <file
Leider wurden wir von einem Bash-Entwicklungsteam der Superlative enttäuscht.
Um ein Array an eine Funktion zu übergeben, gibt es wirklich nur eine Option, nämlich die Verwendung der Funktion nameref:
function funky() {
local -n ARR
ARR=$1
echo "indexes: ${!ARR[@]}"
echo "values: ${ARR[@]}"
}
declare -A HASH
HASH=([foo]=bar [zoom]=fast)
funky HASH # notice that I'm just passing the word 'HASH' to the function
führt zu folgender Ausgabe:
indexes: foo zoom
values: bar fast
Da dies als Referenz übergeben wird, können Sie dem Array in der Funktion auch zuweisen. Ja, das Array, auf das verwiesen wird, muss einen globalen Bereich haben, aber das sollte keine allzu große Sache sein, wenn man bedenkt, dass es sich um Shell-Scripting handelt. Um ein assoziatives oder dünn indiziertes Array nach Wert an eine Funktion zu übergeben, müssen alle Indizes und Werte als einzelne Zeichenfolgen wie folgt in die Argumentliste geworfen werden (nicht allzu nützlich, wenn es sich um ein großes Array handelt):
funky "${!array[*]}" "${array[*]}"
und dann eine Reihe von Code in die Funktion schreiben, um das Array wieder zusammenzusetzen.