Ich möchte die myscript
Datei folgendermaßen aufrufen :
$ ./myscript -s 45 -p any_string
oder
$ ./myscript -h #should display help
$ ./myscript #should display help
Meine Anforderungen sind:
getopt
hier, um die Eingabeargumente zu erhalten- Überprüfen Sie
-s
, ob vorhanden, wenn kein Fehler zurückgegeben wird - Überprüfen Sie, ob der Wert nach
-s
45 oder 90 beträgt - Überprüfen Sie, ob das
-p
vorhanden ist und danach eine Eingabezeichenfolge vorhanden ist - Wenn der Benutzer die Hilfe eingibt
./myscript -h
oder gerade./myscript
anzeigt
Ich habe bisher diesen Code ausprobiert:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Aber mit diesem Code bekomme ich Fehler. Wie geht das mit Bash und getopt
?
-s
, machen Sie ihn zu einem Positionsargument :./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
tatsächlich eine Option ist (dh Ihr Programm kann fortgesetzt werden, wenn es nicht vorhanden ist). In diesem Fall,./myscript 45 -p any_string
. (Ich denke, dasgetopt
kann gemischte Optionen und Positionsargumente verarbeiten, während derbash
eingebaute Befehlgetopts
erfordert, dass alle Positionsargumente nach Optionen platziert werden.)Antworten:
Beispielläufe:
quelle
usage()
wirklich 1 zurückgeben?-h
es aufgerufen wird, es zurückkehren sollte0
, wenn es auf ein nicht existierendes Flag trifft>0
(der Einfachheit halber habe ich nicht zwischen diesen Fällen unterschieden und niemand zwingt Sie, den Verwendungstext im letzteren Fall zu drucken). . Ich habe Programme gesehen , die immer wieder zurückkehren!= 0
, aber auch auf-h/--help
. Vielleicht sollte ich das Snippet aktualisieren, falls Leute es als Boilerplate verwenden (ich hoffe nicht)?getopts
') Design, es gibt keine "optionalen Argumente" mitgetopts
. Der Parser kann einfach nicht wissen, ob das nächste Token ein Argument für die aktuelle Option oder eine Option für sich ist, da dies-p
möglicherweise der beabsichtigte Wert ist. Sie können dies umgehen, wenn Sie absolut wissen, dass ein Optionsparameter nicht wie eine andere gültige Option aussehen kann, ja, aber man könnte sagen, dass es einen Grund gibt, warum optionale Argumente in POSIX nicht definiert sind.bash
Lexer sozusagen nur bei der Identifizierung von Variablen. Sie werden in vielen Fällen nicht benötigt und die Tatsache, dass ich sie immer benutze, ist nur eine Frage des persönlichen Codierungsstils. Für mich ist es einfacher (und hübscher), sie einfach immer zu verwenden, anstatt sich an die Parsing-Regeln in Bezug auf Mehrdeutigkeiten zu erinnern. Ziemlich genau das gleiche, warum manif (foo) { bar; }
stattif (foo) bar;
in einer Sprache im C-Stil schreiben würde (Ästhetik und / oder Vermeidung alberner Fehler).Das Problem mit dem Originalcode ist, dass:
h:
erwartet Parameter, wo es nicht sollte, also ändern Sie es in nurh
(ohne Doppelpunkt)-p any_string
, müssen Siep:
der Argumentliste hinzufügenGrundsätzlich
:
bedeutet die Option, dass das Argument erforderlich ist.Die grundlegende Syntax von
getopts
ist (siehe :)man bash
:wo:
OPTSTRING
ist eine Zeichenfolge mit einer Liste der erwarteten Argumente.h
- auf Option-h
ohne Parameter prüfen ; gibt Fehler bei nicht unterstützten Optionen aus;h:
- Option-h
mit Parameter prüfen ; gibt Fehler bei nicht unterstützten Optionen an;abc
- Check für Optionen-a
,-b
,-c
; gibt Fehler bei nicht unterstützten Optionen an;:abc
- Check für Optionen-a
,-b
,-c
; Stummschalten von Fehlern bei nicht unterstützten Optionen;Hinweise: Mit anderen Worten, der Doppelpunkt vor den Optionen ermöglicht es Ihnen, die Fehler in Ihrem Code zu behandeln. Die Variable enthält
?
bei nicht unterstützten Optionen und:
bei fehlenden Werten.OPTARG
- wird auf den aktuellen Argumentwert gesetzt,OPTERR
- Gibt an, ob Bash Fehlermeldungen anzeigen soll.Der Code kann also sein:
Anwendungsbeispiel:
Siehe: Kleine getopts Tutorial im Bash Hackers Wiki
quelle
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Es berücksichtigt nur ein einzelnes Leerzeichen vor der Buchstabenoption, entfernt das # aus dem Kommentar und stellt ein '-' vor die Buchstabenoption, um den Befehl klarer zu machen.:
ich konnte nicht das Richtige finden, bis ich diese Notizen sah. Wir müssen:
den Optionen, bei denen wir ein Argument erwarten, ein hinzufügen .Verwenden
getopt
Warum getopt?
Um ausgearbeitete Befehlszeilenargumente zu analysieren, um Verwirrung zu vermeiden und die Optionen zu klären, die wir analysieren, damit der Leser der Befehle verstehen kann, was passiert.
Was ist getopt?
getopt
wird verwendet, um Optionen in Befehlszeilen aufzuteilen (zu analysieren), um das Parsen durch Shell-Prozeduren zu vereinfachen und um nach legalen Optionen zu suchen. Dazu werden die GNU-getopt(3)
Routinen verwendet.getopt
kann folgende Arten von Optionen haben.Hinweis: In diesem Dokument wird während der Erläuterung der Syntax Folgendes erläutert:
WIE BENUTZEN
getopt
?Syntax: Erste Form
Beispiele:
Hier sind h, v, t die Optionen und -h -v -t ist, wie Optionen in der Befehlszeile angegeben werden sollen.
In optionalen Parametern kann value mit der Option keine Leerzeichen-Trennung aufweisen. Im Beispiel "-t123" ist -t also Option 123 ist Wert.
Syntax: Zweite Form
Hier wird getopt in fünf Teile geteilt
Beispiele
Syntax: Dritte Form
Hier wird getopt in fünf Teile geteilt
Beispiele
GETOPT_OPTIONS
getopt_options ändert die Art und Weise, wie Befehlszeilenparameter analysiert werden.
Nachfolgend einige der getopt_options
Option: -l oder --longoptions
Beispielsweise
--name=Karthik
wird eine lange Option in der Befehlszeile gesendet. In getopt werden lange Optionen verwendetDa name: angegeben ist, sollte die Option einen Wert enthalten
Option: -a oder --alternative
Beispiel, anstatt
--name=Karthik
Sie könnten nur verwenden-name=Karthik
Ein vollständiges Skriptbeispiel mit dem Code:
Ausführen dieser Skriptdatei:
quelle
Das mit verpackte Beispiel
getopt
(meine Distribution hat es eingefügt/usr/share/getopt/getopt-parse.bash
) sieht so aus, als würde es alle Ihre Fälle abdecken:quelle
Ich weiß, dass dies bereits beantwortet wurde, aber für die Aufzeichnung und für jeden mit den gleichen Anforderungen wie ich habe ich beschlossen, diese verwandte Antwort zu posten. Der Code wird mit Kommentaren überflutet, um den Code zu erklären.
Aktualisierte Antwort:
Speichern Sie die Datei als
getopt.sh
:Dann können Sie es so verwenden:
Alte Antwort:
Ich musste kürzlich einen generischen Ansatz verwenden. Ich bin auf diese Lösung gestoßen:
Ich habe das nicht grob getestet, also könnte ich ein paar Fehler darin haben.
quelle
getopts
in einer Funktion verwenden, fügen Sielocal OPTIND OPTARG
der Funktion hinzugetopts
POSIX 7 Beispiel
Es lohnt sich auch, das Beispiel aus dem Standard zu überprüfen: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
Und dann können wir es ausprobieren:
In Ubuntu 17.10 getestet,
sh
ist Bindestrich 0.5.8.quelle
"getops" und "getopt" sind sehr begrenzt. Während "getopt" empfohlen wird, überhaupt nicht verwendet zu werden, bietet es lange Optionen. Wobei "getopts" nur Einzelzeichenoptionen wie "-a" "-b" zulässt. Es gibt noch ein paar weitere Nachteile, wenn Sie einen von beiden verwenden.
Also habe ich ein kleines Skript geschrieben, das "getopts" und "getopt" ersetzt. Es ist ein Anfang, es könnte wahrscheinlich viel verbessert werden.
Update 08-04-2020 : Ich habe Unterstützung für Bindestriche hinzugefügt, z. B. "--package-name".
quelle