Ich habe gerade herausgefunden, dass getopt
ist nicht plattformübergreifend (insbesondere für FreeBSD und Linux). Was ist die beste Problemumgehung für dieses Problem?Cross-Plattform-getopt für ein Shell-Skript
Antwort
Verwenden Sie getopts
(mit einem "s").
Nach Bash FAQ 35:
Es sei denn, es ist die Version von util-linux, und Sie seinen erweiterten Modus nie getopt verwenden (1). getopt kann keine leeren Argumente oder Argumente mit eingebetteten Leerzeichen verarbeiten. Bitte vergiss, dass es jemals existiert hat.
Die POSIX-Shell (und andere) bieten getopts, die stattdessen sicher verwendet werden können.
Ich benutze die Mnemonic "S" für Shell, getopt "S" ist in BASH –
@Dennis Williamson Bitte aktualisieren Sie Ihre Antwort: Nach dem (aktualisierten) FAQ-Eintrag: ** Es sei denn, die Version von util-linux, und Sie Verwenden Sie den erweiterten Modus, verwenden Sie nie getopt (1). ... ** – Florian
@Florian: Aktualisiert. Vielen Dank. –
Die grundlegende Syntax für getopt
ist plattformübergreifend.
getopt vi: -v -i 100 file
Es gibt im Wesentlichen zwei Versionen des Befehls getopt
: die Originalversion und die erweiterte GNU-Version. Die GNU Enhanced Version ist abwärtskompatibel zur Originalversion. Wenn Sie also nur die Funktionen der Originalversion verwenden, wird es mit beiden funktionieren.
ermitteln, welche Version von getopt verfügbar ist
können Sie erkennen, welche Version verfügbar ist und die erweiterten Funktionen verwenden, wenn der GNU erweiterte Version verfügbar ist, und sich auf die ursprünglichen Funktionen zu begrenzen, wenn der GNU erweiterte Version ist Nicht verfügbar. Die erweiterte Version verfügt über eine -T
Option zum Testen, welche Version verfügbar ist.
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
set -- `getopt --long help,output:,version --options ho:v -- "[email protected]"`
else
# Original getopt is available
set -- `getopt ho:v "[email protected]"`
fi
Betrachten Sie mit Hilfe der integrierten in Shell-Befehl getopts
(mit einem "s") statt, weil es mehr tragbar ist. getopts
unterstützt jedoch keine langen Optionen (z. B. --help
).
Wenn Sie lange Optionen mögen, verwenden Sie getopt
und verwenden Sie den obigen Test, um zu sehen, ob die GNU Enhanced Version von getopt
verfügbar ist oder nicht. Wenn die erweiterte Version nicht verfügbar ist, kann das Skript die ursprüngliche Version von getopt
(ohne Unterstützung für lange Optionsnamen und keine Whitespace-Unterstützung) oder getopts
(ohne Unterstützung für lange Optionsnamen) ordnungsgemäß herabsetzen.
Mit GNU verbesserte getopt richtig
die GNU erweiterte Version Erste Argumente mit Leerzeichen zu verarbeiten richtig ist schwierig. Hier ist, wie es gemacht wird:
ARGS=`getopt --long help,output:,verbose --options ho:v -- "[email protected]"`
if [ $? -ne 0 ]; then
echo "Usage error (use -h for help)" >&2
exit 2
fi
eval set -- $ARGS
# Parameters are now sorted: options appear first, followed by --, then arguments
# e.g. entering: "foo bar" -o abc baz -v
# produces: -o 'abc' -v -- 'foo bar' 'baz'
Das Geheimnis ist "[email protected]"
zu verwenden, wo die doppelten Anführungszeichen sehr wichtig sind (in Zeile 1), und auf eval
die gesetzt Befehl (in Zeile 6).
So können Fehler von getopt
erkannt und behandelt werden, der Aufruf an getopt
erfolgt getrennt von der eval
mit den beiden durch die ARGS-Variable verknüpft.
Komplettes Arbeits Beispiel
PROG=`basename $0`
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
ARGS=`getopt --name "$PROG" --long help,output:,verbose --options ho:v -- "[email protected]"`
else
# Original getopt is available (no long option names, no whitespace, no sorting)
ARGS=`getopt ho:v "[email protected]"`
fi
if [ $? -ne 0 ]; then
echo "$PROG: usage error (use -h for help)" >&2
exit 2
fi
eval set -- $ARGS
while [ $# -gt 0 ]; do
case "$1" in
-h | --help) HELP=yes;;
-o | --output) OUTFILE="$2"; shift;;
-v | --verbose) VERBOSE=yes;;
--) shift; break;; # end of options
esac
shift
done
if [ $# -gt 0 ]; then
# Remaining parameters can be processed
for ARG in "[email protected]"; do
echo "$PROG: argument: $ARG"
done
fi
echo "$PROG: verbose: $VERBOSE"
echo "$PROG: output: $OUTFILE"
echo "$PROG: help: $HELP"
Dieses Beispiel kann aus https://gist.github.com/hoylen/6607180
Die Vergleichstabelle auf Wikipedia's entry on getopts vergleicht die verschiedenen Funktionen heruntergeladen werden.
Ja, 'getopts' (mit einem s) ist eine andere Option. Portabilität puristen würden immer noch getopt bevorzugen, da getopts in alten Bourne-Shells vor 1986 nicht verfügbar war, aber das ist ein schlechter Grund, da die meisten/modernen Shells Optionen bekommen. Ein besserer Grund ist es, GNU enhanced getup einfach zu nutzen, wenn es verfügbar ist. Das GNU Enhanced getopt erlaubt Operanden, mit Optionen gemischt zu werden und unterstützt lange Optionsnamen (beide Funktionen, die getopts nicht unterstützt - siehe [Vergleichstabelle] [1]). – Hoylen
Warum gibt es ein leeres '-', wenn ich 'eval set - $ ARGS' starte? Es ist sehr irritierend. – Hindol
Die Bash gebautet getopts Funktion kurze und lange Optionen verwendet werden können, portabel zu analysieren, finden Sie unter:
Using getopts in bash shell script to get long and short command line options
- 1. Asynchrone Shellskript in Cocoa-Applescript?
- 2. Shellskript ausführen, wenn ein neuer Benutzer erstellt wird
- 3. Apple Remote Desktop-Shellskript unter bestimmten Bedingungen aktivieren
- 4. Übergeben Sie Argumente in Anführungszeichen an Shellskript und führen Sie das Anführungszeichen
- 5. So löschen Sie das Ende der Zeichenfolge im Shellskript der CSV-Datei?
- 6. Kann ich programmieren, um eine freie CPU zu wählen, habe ich mehrere, mein Shellskript laufen zu lassen?
- 7. Abfrage für ein Suchformular
- 8. addMouseListener für ein JPanel
- 9. Algorithmus für ein Grafikproblem
- 10. Ein-/Ausblenden für MAAttachedWindow
- 11. Javascript für ein Gesundheitswerkzeug
- 12. Textänderungsbenachrichtigung für ein NSTextField
- 13. Ein Warteschlangensystem für Perl
- 14. -initWithContentsOfFile: für ein NSMutableArray
- 15. Gesamtbetragssteuer für ein Produkt
- 16. Entwurf für ein Szenario
- 17. CouchDB für ein Forum?
- 18. Standardfunktion für ein Objekt?
- 19. Jeder für ein Objekt?
- 20. Maximalwert für ein Jahr
- 21. Ein Juwel für ein Rails-Projekt verprellen
- 22. Ist ein DBMS ein Beispiel für Middleware?
- 23. ein Verhalten für ein kontinuierlich messbares Phänomen
- 24. Ein Arbeitsbeispiel für ein Projekt mit Rebar3
- 25. ein Protokoll für ein Bündel in servicemix
- 26. Validierung für TextBox für ein Benutzerformular
- 27. InterfaceError für ein benutzerdefiniertes JSONField für Django
- 28. Wie kann ich 1000 Dateien erstellen, mit denen ich ein Skript testen kann?
- 29. Gibt es ein Tool für Refactoring SQL, ein bisschen wie ein ReSharper für SQL
- 30. Vermisster Rekursionscode für ein Brettspiel
Wenn Sie begann mit aus GNU getopt mit langen Optionen etc, und schauen, um Ihre vorhandenen Code machen Portable mit so wenig Änderungen wie möglich, dann finden Sie http://stackoverflow.com/a/37087374/324105 nützlich. – phils