Es gibt einen getopt
Befehl in der Bash-Befehlszeile. getopt
kann mit kurzen Optionen (wie getopt -o axby "$@"
) verwendet werden und kann sowohl mit kurzen als auch mit langen Optionen (wie getopt -o axby -l long-key -- "$@"
) verwendet werden, aber jetzt brauche ich nur lange Optionen (dh kurze Optionen gibt es überhaupt nicht), der Befehl getopt -l long-key -- "$@"
jedoch nicht --long-key
Option richtig analysieren . Wie kann ich einen getopt
Befehl nur mit langen Optionen verwenden? Oder ist es unmöglich oder ist es nur ein Fehler des getopt
Befehls?
12
getopts
, aber Sie verwenden den/usr/bin/getopt
Befehl.Antworten:
getopt
ist vollkommen in Ordnung, wenn man keine kurzen Optionen hat. Aber Sie müssen ihm sagen, dass Sie keine kurzen Möglichkeiten haben. Es ist eine Kuriosität in der Syntax - aus dem Handbuch:Das ist, was in Ihrem Test passiert:
getopt -l long-key -- --long-key foo
Behandelt--long-key
als die Liste der Optionen-egklnoy
undfoo
als das einzige Argument. Verwendenz.B
quelle
getopts
undgetopt
infiziert? Sie beginnen mit dem Kommentierengetopts
und erwähnen dann nur nochgetopt
.getopt
Programm von GNU coreutils, worum es in der Frage geht. Ich habe den besagten Text korrigiertgetopts
. Vielen Dank.getopts
macht nicht einmal lange Optionen, also würde nichts davon zutreffengetopts
.getopts
Tag. Ich wollte deine Antwort nicht ändern, weil du normalerweise viel besser weißt als ich, worüber du schreibst :-)Weiß nicht über ,
getopt
aber diegetopts
builtin kann nur lange Optionen wie das zu handhaben verwendet werden:Natürlich funktioniert das so wie es ist nicht, wenn die long-Optionen Argumente haben sollen. Es kann aber gemacht werden, wie ich gelernt habe, daran zu arbeiten. Während ich es anfangs hier aufgenommen habe, wurde mir klar, dass es für Long-Optionen nicht sehr nützlich ist. In diesem Fall verkürzte es meine
case
(match)
Felder nur um ein einziges vorhersehbares Zeichen. Was ich jetzt weiß, ist, dass es sich hervorragend für kurze Optionen eignet - es ist am nützlichsten, wenn es eine Zeichenkette unbekannter Länge durchläuft und einzelne Bytes gemäß ihrer Optionszeichenkette auswählt. Aber wenn die Option ist die arg, es gibt wenig , was man mit einer tustfor var do case $var in
Kombination , die es tun könnte. Ich denke, es ist besser, es einfach zu halten.Ich vermute, dasselbe gilt,
getopt
aber ich weiß nicht genug darüber, um es mit Sicherheit zu sagen. In Anbetracht der folgenden arg Array, werde ich meine eigene kleine arg Parser zeigen - die in erster Linie auf der evalation / Zuordnung Beziehung hängt Ich bin gekommen , um zu schätzen ,alias
und$((shell=math))
.Das ist die Arg-Saite, mit der ich arbeiten werde. Jetzt:
Dabei wird das arg-Array auf zwei verschiedene Arten verarbeitet, je nachdem, ob Sie ein oder zwei durch das
--
Trennzeichen getrennte Argumente übergeben . In beiden Fällen gilt dies für Verarbeitungssequenzen für das arg-Array.Wenn du es so nennst:
Seine erste
acase()
Aufgabe wird es sein, seine Funktion so zu schreiben , dass sie so aussieht:Und neben
shift 3
. Die Befehlsersetzung in deracase()
Funktionsdefinition wird ausgewertet, wenn die aufrufende Shell die Eingaben der Funktion in diesem Dokument erstellt, sie wird jedochacase()
niemals in der aufrufenden Shell aufgerufen oder definiert. Der Aufruf erfolgt jedoch in der Subshell. Auf diese Weise können Sie die gewünschten Optionen dynamisch in der Befehlszeile angeben.Wenn Sie ein Array ohne Trennzeichen übergeben, werden nur
acase()
Übereinstimmungen für alle Argumente eingetragen, die mit der Zeichenfolge beginnen--
.Die Funktion führt praktisch die gesamte Verarbeitung in der Subshell aus. Dabei werden die einzelnen Werte des Args iterativ in Aliasnamen gespeichert, denen assoziative Namen zugewiesen sind. Wenn es durch ist, druckt es jeden Wert aus, mit
alias
dem es gespeichert hat. Dies ist POSIX-spezifiziert, um alle gespeicherten Werte so zu drucken, dass ihre Werte wieder in die Shell eingegeben werden können. Also, wenn ich es tue ...Die Ausgabe sieht folgendermaßen aus:
Beim Durchlaufen der Argumentliste wird nach einer Übereinstimmung mit dem case-Block gesucht. Wenn es dort eine Übereinstimmung findet, wirft es eine Flagge -
f=optname
. Bis es wieder eine gültige Option findet, wird jedes nachfolgende Argument zu einem Array hinzugefügt, das es basierend auf dem aktuellen Flag erstellt. Wenn dieselbe Option mehrmals angegeben wird, werden die Ergebnisse zusammengesetzt und nicht überschrieben. Alles, was nicht der Fall ist - oder Argumente, die auf ignorierte Optionen folgen -, werden einem ignorierten Array zugewiesen .Die Ausgabe wird von der Shell automatisch für die Shell-Eingabe gespeichert.
... sollte absolut sicher sein. Wenn es aus irgendeinem Grund nicht sicher ist, sollten Sie wahrscheinlich einen Fehlerbericht bei Ihrem Shell-Betreuer einreichen.
Es werden zwei Arten von Aliaswerten für jede Übereinstimmung zugewiesen. Erstens wird ein Flag gesetzt - dies geschieht unabhängig davon, ob eine Option nicht übereinstimmenden Argumenten vorangeht oder nicht. Jedes Vorkommen von
--flag
in der Argumentliste wird also ausgelöstflag=1
. Das verbindet nicht - wird--flag --flag --flag
nurflag=1
. Dieser Wert hat Zuwachs obwohl - für alle Argumente , die ihm folgen könnten. Es kann als Indexschlüssel verwendet werden. Nachdem ich daseval
oben Genannte getan habe, kann ich Folgendes tun:...bekommen...
Und so:
AUSGABE
Und zu Argumenten, die nicht passen, würde ich im obigen Feld ignoriert ersetzen
for ... in
, um zu bekommen:quelle