Ich versuche, Arrays in der Bourne-Shell ( /bin/sh
) zu verwenden. Ich fand, dass der Weg zum Initialisieren von Array-Elementen ist:
arr=(1 2 3)
Aber es ist ein Fehler aufgetreten:
syntax error at line 8: `arr=' unexpected
In dem Beitrag, in dem ich diese Syntax gefunden habe, heißt es, dass sie bash
für die Bourne-Shell bestimmt ist , aber ich konnte keine separate Syntax finden. Steht die Syntax /bin/sh
auch gleich?
shell
array
bourne-shell
SubhasisM
quelle
quelle
Antworten:
/bin/sh
ist heutzutage auf keinem System mehr eine Bourne-Shell (selbst Solaris, das als eines der letzten großen Systeme einbezogen wurde, hat in Solaris 11 für / bin / sh auf POSIX sh umgestellt)./bin/sh
war die Thompson-Shell in den frühen 70er Jahren. Die Bourne-Shell ersetzte sie 1979 in Unix V7./bin/sh
ist seit vielen Jahren die Bourne-Shell (oder die Almquist-Shell, eine kostenlose Neuimplementierung von BSDs).Heutzutage
/bin/sh
ist eher ein Dolmetscher oder ein anderer für die POSIXsh
Sprache, der selbst auf einer Teilmenge der Sprache von ksh88 (und einer Obermenge der Bourne-Shell-Sprache mit einigen Inkompatibilitäten) basiert.Die Bourne-Shell oder die POSIX-Sprachspezifikation unterstützen keine Arrays. Oder besser gesagt sie haben nur ein Array: die Positionsparameter (
$1
,$2
,$@
, so ein Array pro Funktion als auch).ksh88 hatte Arrays, die Sie eingestellt haben
set -A
, aber diese wurden in POSIX sh nicht angegeben, da die Syntax umständlich und wenig benutzerfreundlich ist.Andere Schalen mit Array / Listen Variablen umfassen:
csh
/tcsh
,rc
,es
,bash
(was meistens der KSH Syntax der ksh93 Weise kopiert),yash
,zsh
, diefish
jeweils mit einer anderen Syntax (rc
die Schale des einmal zu-sein Nachfolger von Unix,fish
undzsh
wobei die beständigsten Einsen)...Standardmäßig
sh
(funktioniert auch in modernen Versionen der Bourne-Shell):(Beachten Sie, dass in der Bourne-Shell und in ksh88
$IFS
das Leerzeichen enthalten sein muss"$@"
, damit es ordnungsgemäß funktioniert (ein Fehler), und dass Sie in der Bourne-Shell nicht auf die obigen Elemente zugreifen können$9
(${10}
nicht funktionieren, Sie können immer noch eineshift 1; echo "$9"
Schleife ausführen oder einen Loop ausführen) Sie)).quelle
"${@:2:4}"
. Natürlich sehe ich die Ähnlichkeiten , aber ich betrachte Positionsparameter nicht als Array an sich."$@"
wirkt wie ein Array (wie die Anordnungen voncsh
,rc
,zsh
,fish
,yash
...), es ist mehr die Korn / bash „arrays“ , die nicht wirklich Arrays sind, aber einige Form von assoziativen Arrays mit Schlüsseln, die auf positive Ganzzahlen beschränkt sind (sie haben auch Indizes, die bei 0 anstelle von 1 beginnen, wie in allen anderen Shells mit Arrays und "$ @"). Shells, die Slicing unterstützen, können ebenfalls $ @ in Scheiben schneiden (wobei ksh93 / bash den Positionsparametern umständlich $ 0 hinzufügt, wenn Sie "$ @" in Scheiben schneiden).In der einfachen Bourne-Shell gibt es keine Arrays. Sie können ein Array auf folgende Weise erstellen und durchlaufen:
Unabhängig davon, in welcher Weise Arrays verwendet
sh
werden, ist dies immer umständlich. Ziehen Sie in Betracht, eine andere Sprache zu verwenden, z. B.Python
oderPerl
wenn Sie können, es sei denn, Sie haben eine sehr eingeschränkte Plattform oder möchten etwas lernen.quelle
$(...)
Syntax. Sie müssen also in der Tat die Bourne-Shell haben. Sind Sie auf Solaris 10 oder früher? Möglicherweise haben Sie auch keineseq
. Unter Solaris 10 und früheren Versionen soll / usr / xpg4 / bin / sh einen Standardsh
anstelle einer Bourne-Shell haben. Aufseq
diese Weise ist es auch nicht sehr gut.seq
dieses Weges nicht gut?$(...)
über`
, aber die OP ist/bin/sh
wahrscheinlich eine Bourne - Shell, kein POSIX - Shell. Neben der Tatsache, dass es sichseq
nicht um einen Standardbefehl handelt,$(seq 100)
bedeutet dies, dass die gesamte Ausgabe im Speicher abgelegt wird. Dies hängt vom aktuellen Wert von $ IFS ab, der Zeilenvorschub enthält und keine Ziffern enthält. Am besten zu verwendeni=1; while [ "$i" -le 100 ]; ...; i=$(($i + 1)); done
(obwohl das auch in der Bourne-Shell nicht funktioniert)./bin/sh
Syntax, lässt die Leute denken, dass es in Ordnung ist, den falschen#!/bin/sh
Schebang zu verwenden, und bricht dann ihre Skripte, wenn andere Leute versuchen, sie zu verwenden. Sie sind gut beraten, diese Art von Flammenschwarm nicht zu veröffentlichen. :)Wie die anderen gesagt haben, hat die Bourne Shell keine echten Arrays.
Abhängig davon, was Sie tun müssen, sollten jedoch durch Trennzeichen getrennte Zeichenfolgen ausreichen:
Wenn die typischen Trennzeichen (Leerzeichen, Tabulator und Zeilenvorschub) nicht ausreichen, können
IFS
Sie vor der Schleife ein beliebiges Trennzeichen festlegen .Und wenn Sie das Array programmgesteuert erstellen müssen, können Sie einfach eine durch Trennzeichen getrennte Zeichenfolge erstellen.
quelle
split+glob
Operator) nicht in Anführungszeichen setzen .Eine Möglichkeit, Arrays im Bindestrich zu simulieren (kann für eine beliebige Anzahl von Dimensionen eines Arrays angepasst werden): (Beachten Sie, dass für die Verwendung des
seq
Befehls dieIFS
Einstellung '' (SPACE = der Standardwert) erforderlich ist. Sie könnenwhile ... do ...
oder verwendendo ... while ...
Schleifen stattdessen, um dies zu vermeiden (ich habeseq
im Rahmen einer besseren Veranschaulichung dessen, was der Code tut, gehalten).quelle
local
von beidenbash
und unterstützt wird unddash
nicht POSIX ist.seq
ist auch kein POSIX-Befehl. Sie sollten wahrscheinlich erwähnen, dass Ihr Code einige Annahmen über den aktuellen Wert von $ IFS macht (wenn Sie die Verwendungseq
und Anführungszeichen Ihrer Variablen vermeiden , kann dies vermieden werden)