Derzeit schreibe ich ein Bash-Skript, das die folgenden Anforderungen erfüllt:
- Es sollte auf einer Vielzahl von Unix / Linux-Plattformen laufen
- Es sollte sowohl kurze als auch (GNU) lange Optionen unterstützen
Ich weiß, dass getopts
dies in Bezug auf die Portabilität der bevorzugte Weg wäre, aber AFAIK unterstützt keine langen Optionen.
getopt
unterstützt lange Optionen, aber der BashGuide rät dringend davon ab:
Verwenden Sie niemals getopt (1). getopt kann keine leeren Argumente, Strings oder Argumente mit eingebettetem Whitespace verarbeiten. Bitte vergessen Sie, dass es jemals existiert hat.
Es besteht also weiterhin die Möglichkeit des manuellen Parsens. Dies ist fehleranfällig, führt zu ziemlich viel Code auf der Kesselplatte und ich muss Fehler selbst behandeln (ich denke getopt(s)
, Fehler werden von selbst behoben).
Was wäre in diesem Fall die bevorzugte Wahl?
bash
shell-script
options
user-interface
getopts
Hilfemethode
quelle
quelle
Antworten:
Wenn es auf eine Reihe von Unices portierbar sein soll, müssen Sie sich an POSIX sh halten. Und AFAIU dort haben Sie einfach keine andere Wahl, als das rollierende Argumentieren von Hand.
quelle
getopt
vsgetopts
scheint eine religiöse Angelegenheit zu sein. Zu den Argumenten dagegengetopt
in den Bash-FAQ :"
getopt
Kann keine leeren Argumente verarbeiten" bezieht sich anscheinend auf ein bekanntes Problem mit optionalen Argumenten, das anscheinendgetopts
überhaupt nicht unterstützt wird (zumindest beim Lesenhelp getopts
für Bash 4.2.24). Vonman getopt
:Ich weiß nicht, woher die
getopt
[...] Argumente mit eingebettetem Whitespace kommen, aber testen wir sie:test.sh:
Lauf:
Sieht für mich nach Scheck und Kumpel aus, aber ich bin sicher, jemand wird zeigen, wie ich den Satz völlig missverstanden habe. Natürlich bleibt das Problem der Portabilität bestehen. Sie müssen entscheiden, wie viel Zeit es wert ist, in Plattformen mit einem älteren oder keinem verfügbaren Bash zu investieren. Mein eigener Tipp ist, die YAGNI- und KISS- Richtlinien zu verwenden - Entwickeln Sie nur für die spezifischen Plattformen, von denen Sie wissen, dass sie verwendet werden. Die Portabilität von Shell-Code beträgt im Allgemeinen 100%, da die Entwicklungszeit unendlich ist.
quelle
getopt
Sie hier zitieren, Linux-spezifisch ist. Beachten Sie, dass diesgetopt
nicht Teil von istbash
, nicht einmal ein GNU-Dienstprogramm und unter Linux mit dem Paket util-linux ausgeliefert wird.getopt
, nur Linux AFAIK kommt mit einer, die lange Optionen oder Leerzeichen in Argumenten unterstützt. Die anderen unterstützen nur die System V-Syntax.getopt
ist ein traditioneller Befehl, der lange vor der Veröffentlichung von Linux von System V stammt.getopt
wurde nie standardisiert. Keiner von POSIX, Unix oder Linux (LSB) hat dengetopt
Befehl jemals standardisiert .getopts
wird in allen drei angegeben, jedoch ohne Unterstützung für lange Optionen.getopt
. Es ist das Linux-Utensilien-Aroma, wie es von @ StéphaneChazelas angezeigt wird. Es verfügt über Legacy-Optionen, die die oben beschriebene Syntax deaktivieren. Insbesondere die Manpage "GETOPT_COMPATIBLE" erzwingt, dass getopt das erste in SYNOPSIS angegebene Aufrufformat verwendet. Wenn Sie jedoch erwarten können, dass auf den Zielsystemen dieses Paket installiert ist, ist dies der richtige Weg, da das ursprüngliche getopt schrecklich und das getopt von Bash sehr begrenzt istEs gibt diese getopts_long als POSIX-Shell-Funktion, die Sie in Ihr Skript einbetten können.
Beachten Sie, dass Linux
getopt
(vonutil-linux
) korrekt funktioniert, wenn es sich nicht im herkömmlichen Modus befindet und lange Optionen unterstützt. Es ist jedoch wahrscheinlich keine Option für Sie, wenn Sie auf andere Unices portierbar sein müssen.Neuere Versionen von ksh93 (
getopts
) und zsh (zparseopts
) bieten eine integrierte Unterstützung für das Parsen langer Optionen, die für Sie möglicherweise eine Option sind, da sie für die meisten Unices verfügbar sind (obwohl sie häufig nicht standardmäßig installiert sind).Eine andere Option wäre die Verwendung
perl
undGetopt::Long
das zugehörige Modul, die heutzutage auf den meisten Unices verfügbar sein sollten, entweder durch Schreiben des gesamten Skriptsperl
oder einfach durch Aufrufen von Perl, um die Option zu analysieren und die extrahierten Informationen an die Shell weiterzuleiten . So etwas wie:Sehen Sie,
perldoc Getopt::Long
was es kann und wie es sich von anderen Optionsparsern unterscheidet.quelle
In jeder Diskussion zu diesem Thema wird die Option hervorgehoben, den Parsing-Code manuell zu schreiben - nur dann können Sie sich über die Funktionalität und Portabilität sicher sein. Ich rate Ihnen, keinen Code zu schreiben, den Sie mit benutzerfreundlichen Open-Source-Codegeneratoren generieren und erneut generieren können. Verwenden Sie Argbash , um die endgültige Antwort auf Ihr Problem zu finden. Es ist ein gut dokumentierter Codegenerator, der als Befehlszeilenanwendung , online oder als Docker-Image verfügbar ist .
Ich rate von Bash-Bibliotheken ab, von denen einige verwenden
getopt
(was ziemlich unportabel ist), und es ist mühsam, einen gigantischen unlesbaren Shell-Blob mit Ihrem Skript zu bündeln.quelle
Sie können es
getopt
auf Systemen verwenden, die es unterstützen, und ein Fallback für Systeme verwenden, die dies nicht tun.Zum Beispiel
pure-getopt
wird in pure Bash implementiert, um ein Ersatz für GNU zu seingetopt
.quelle