Gibt es eine präzise Möglichkeit, die Array-Unterstützung durch die lokale Bourne-ähnliche Shell in der Befehlszeile zu testen?
Das ist immer möglich:
$ arr=(0 1 2 3);if [ "${arr[2]}" != 2 ];then echo "No array support";fi
oder Testen für $SHELL
und Shell-Version:
$ eval $(echo "$SHELL --version") | grep version
und dann die Manpage lesen, vorausgesetzt ich habe Zugriff darauf. (Selbst dort, /bin/bash
wenn ich von schreibe , gehe ich davon aus, dass alle Bourne-ähnlichen Muscheln die lange Option zulassen --version
, wenn dies zum Beispiel für ksh bricht .)
Ich suche nach einem einfachen Test, der unbeaufsichtigt sein und zu Beginn des Skripts oder sogar vor dem Aufruf in einen Verwendungsabschnitt aufgenommen werden kann.
shell-script
shell
array
Cbhihe
quelle
quelle
csh
ist keine Bourne Shell.tcsh
ist auch keiner (es sindcsh
einige Fehler behoben)$SHELL
die bevorzugte Shell des Benutzers ist, ebenso wie$EDITOR
sein bevorzugter Texteditor. Es hat wenig mit der aktuell laufenden Shell zu tun.eval
Die Ausgabe von$SHELL --version
als Shell-Code zu verwenden, macht keinen Sinn.Antworten:
Angenommen , Sie zu Bourne-wie Muscheln einschränken wollen (viele andere Muscheln mögen
csh
,tcsh
,rc
,es
oderfish
Support - Arrays aber ein Skript kompatibel zur gleichen Zeit zu Bourne artigen Schalen zu schreiben und das ist heikel und in der Regel sinnlos , da sie Dolmetscher sind für ganz anderen und Inkompatible Sprachen). Beachten Sie, dass zwischen den Implementierungen erhebliche Unterschiede bestehen.Die Bourne-ähnlichen Shells, die Arrays unterstützen, sind:
ksh88
(Dies ist das erste, das Arrays implementiert. Ksh88 ist immer nochksh
auf den meisten herkömmlichen kommerziellen Unices zu finden, für die es auch die Basis ist.sh
)set -A array foo bar
oderset -A array -- "$var" ...
wenn Sie nicht garantieren können, dass dies$var
nicht mit einem-
oder beginnt+
.0
.a[1]=value
.a[5]=foo
funktioniert auch, wenn siea[0,1,2,3,4]
nicht eingestellt sind, und lässt sie nicht gesetzt.${a[5]}
um auf das Element von Index 5 zuzugreifen (nicht unbedingt das 6. Element, wenn das Array dünn ist). Das5
kann jeder arithmetische Ausdruck sein.${#a[@]}
ist die Anzahl der zugewiesenen Elemente im Array (nicht der größte zugewiesene Index).[[ -n "${a[i]+set}" ]]
).$a
ist das gleiche wie${a[0]}
. Das heißt, Arrays erweitern irgendwie skalare Variablen, indem sie ihnen zusätzliche Werte geben.pdksh
und Derivate (das ist die Basis für dieksh
und manchmalsh
für mehrere BSDs und war die einzige OpenSource-Implementierung von ksh, bevor die Quelle ksh93 freigegeben wurde):Meistens wie
ksh88
aber beachten Sie:set -A array -- foo bar
(die wurden--
dort nicht benötigt).${#a[@]}
ist eins plus der Index des größten zugewiesenen Index. (a[1000]=1; echo "${#a[@]}"
gibt 1001 aus, obwohl das Array nur ein Element enthält.mksh
haben ein paar zusätzlichen Betreiber von inspiriertbash
,ksh93
oderzsh
wie Zuweisungen a laa=(x y)
,a+=(z)
,${!a[@]}
die Liste des zugewiesenen Indizes zu erhalten.zsh
.zsh
Arrays sind im Allgemeinen besser gestaltet und nutzen das Beste ausksh
undcsh
Arrays. Sie sind ähnlich,ksh
aber mit signifikanten Unterschieden:ksh
Emulation), was mit dem Bourne-Array (den Positionsparametern $ @, daszsh
auch als $ argv-Array verfügbar gemacht wird) und dencsh
Arrays übereinstimmt .$a
ist nicht dasselbe wie,${a[0]}
sondern erweitert sich auf die nicht leeren Elemente des Arrays ("${a[@]}"
für alle Elemente wie inksh
).a[5]=1
funktioniert, weist aber allen Elementen von 1 bis 4 die leere Zeichenfolge zu, wenn sie nicht zugewiesen wurden. Also${#a[@]}
(genau wie${#a}
in ksh die Größe des Elements des Index 0) ist die Anzahl der Elemente im Array und der größte zugewiesene Index.a=(x y)
.set -A a x y
funktioniert auch, wird aberset -A a -- x y
nur in der ksh-Emulation unterstützt (dies--
wird in der zsh-Emulation nicht benötigt).ksh93
. (Hier werden die neuesten Versionen beschrieben).ksh93
Das seit langem als experimentell angesehene Experiment findet sich nun in immer mehr Systemen, nachdem es als FOSS veröffentlicht wurde. Zum Beispiel ist es das/bin/sh
(wo es die Bourne-Shell ersetzt hat/usr/xpg4/bin/sh
, auf der die POSIX-Shell noch basiertksh88
) undksh
vonSolaris 11
. Seine Arrays erweitern und verbessern ksh88.a=(x y)
kann verwendet werden, um ein Array zu definieren, aber daa=(...)
es auch zum Definieren von zusammengesetzten Variablen (a=(foo=bar bar=baz)
) verwendet wird,a=()
ist es mehrdeutig und deklariert eine zusammengesetzte Variable, kein Array.a=((0 1) (0 2))
) und Array-Elemente können auch zusammengesetzte Variablen (a=((a b) (c=d d=f)); echo "${a[1].c}"
) sein.a=([2]=foo [5]=bar)
Syntax kann verwendet werden, um dünn besetzte Arrays gleichzeitig zu definieren.zsh
, aber eine große Anzahl von Operatoren wird auch unterstützt, um Arrays zu manipulieren."${!a[@]}"
um die Liste der Array-Indizes abzurufen.bash
.bash
ist die Hülle des GNU-Projekts. Es wird wiesh
in neueren Versionen von OS / X und einigen GNU / Linux-Distributionen verwendet.bash
Arrays emulieren meistensksh88
solche mit einigen Merkmalen vonksh93
undzsh
.a=(x y)
unterstützt.set -A a x y
nicht unterstützt.a=()
Erstellt ein leeres Array (keine zusammengesetzten Variablen inbash
)."${!a[@]}"
für die Liste der Indizes.a=([foo]=bar)
Syntax unterstützt sowie einige andere vonksh93
undzsh
.bash
Versionen unterstützen auch assoziative Arrays als separaten Typ.yash
. Es ist eine relativ neue, saubere, Multi-Byte-fähige POSIX sh-Implementierung. Nicht weit verbreitet. Seine Arrays sind eine weitere saubere API ähnlichzsh
a=(var value)
array
eingebautenarray -s a 5 value
die 5 zu ändern ten Element würde fehlschlagen , wenn das Element nicht vorher zugewiesen wurde.${a[#]}
,${#a[@]}
als eine Liste der Größe der Elemente zu sein.a=("$a")
eine skalare Variable als Array neu definieren, bevor Sie Elemente hinzufügen oder ändern können.sh
.Daraus können Sie die Erkennung der Array-Unterstützung ersehen, mit der Sie Folgendes tun können:
reicht nicht aus, um diese Arrays verwenden zu können. Sie müssen Wrapper-Befehle definieren, um Arrays als Ganzes und einzelne Elemente zuzuweisen, und sicherstellen, dass Sie nicht versuchen, spärliche Arrays zu erstellen.
Mögen
Und dann greifen Sie auf Array - Elemente mit
"${a[$first_indice+n]}"
, die ganze Liste mit"${a[@]}"
und verwenden Sie die Wrapper - Funktionen (array_elements
,set_array
,set_array_element
) die Anzahl der Elemente eines Arrays zu erhalten (in$REPLY
), setzen Sie das Array als Ganzes oder assign einzelnen Elemente.Wahrscheinlich nicht die Mühe wert. Ich würde
perl
das Bourne / POSIX-Shell-Array verwenden oder darauf beschränken :"$@"
.Wenn die Absicht besteht, dass eine Datei von der interaktiven Shell eines Benutzers bezogen wird, um Funktionen zu definieren, die intern Arrays verwenden, finden Sie hier einige weitere nützliche Hinweise.
Sie können
zsh
Arrays so konfigurieren , dass sieksh
Arrays in lokalen Bereichen (in Funktionen oder anonymen Funktionen) ähneln.Sie können auch emulieren
ksh
(die Kompatibilität mitksh
Arrays und mehreren anderen Bereichen verbessern ) mit:In diesem Sinne und Sie sind bereit, die Unterstützung für
yash
undksh88
ältere Versionen vonpdksh
Derivaten einzustellen. Solange Sie nicht versuchen, spärliche Arrays zu erstellen, sollten Sie in der Lage sein, konsequent Folgendes zu verwenden:a[0]=foo
a=(foo bar)
(aber nichta=()
)"${a[#]}"
,"${a[@]}"
,"${a[0]}"
in jenen Funktionen, die das haben
emulate -L ksh
, während derzsh
Benutzer seine Arrays normalerweise noch auf zsh-Weise benutzt.quelle
Sie können
eval
die Array-Syntax ausprobieren:quelle
ksh88
unterstützt Arrays aber nichta=()
. Inksh93
,a=()
deklariert eine Verbindung variabel, kein Array es sei denn , die Variable vorher als Array erklärt wurde.yash
, Sie tun nicht,a[5]=1
aberarray -s a 5 1
ksh93
hat mich überrascht. Würde es Ihnen etwas ausmachen, mir einen Teil der Dokumentation darüber zu geben? Ich füge1
dem Array hinzu, damit es funktioniert.