Es gibt viele Möglichkeiten Parameter, die an ein Bash Script übergeben wurden, zu verarbeiten. Hier zwei ähnliche Varianten, die das Parameterschema -o /foo/
und --output=/foo/
behandeln können. Das zweite Beispiel zeigt zudem noch die Verwendung von Kommandos.
String Manipulation mit Bash-Hausmitteln
Falls du mit String Manipulation (z.B. ${var#=*}
oder Ähnliches) noch nicht vertraut bist, rate ich dir hier weiter zu lesen. In den folgenden Scripten holen wir uns aus Strings immer einen Teilstring. Der Befehl dabei sieht immer wie folgt aus: ${<VARIABLE><SPLIT-CHARS><REGEX>}
Die Split-Chars definieren was hinterher raus kommt, denn das Ergebnis ist immer ein zusammenhängender String. Von denen gibt es vier verschiedene:
# |
Löscht die kürzeste Übereinstimmung vom Anfang an:$var="ab=cd=ef" ${var#*=} Heraus kommt cd=ef , da ab= die kürzeste Übereinstimmung war. |
## |
Löscht die längste Übereinstimmung vom Anfang an:$var="ab=cd=ef" ${var##*=} Heraus kommt ef , da ab=cd= die längste Übereinstimmung war. |
% |
Löscht die kürzeste Übereinstimmung vom Ende an:$var="ab=cd=ef" ${var%=*} (Achtung, der Stern ist jetzt hinter dem Gleich 😉 )Heraus kommt ab=cd , da =ef die kürzeste Übereinstimmung war. |
%% |
Löscht die längste Übereinstimmung vom Ende an:$var="ab=cd=ef" ${var%%=*} Heraus kommt ab , da =cd=ef die längste Übereinstimmung war. |
Wir werden diese Operationen nutzen um Werte für die Parameter zu ermitteln. Bei z.B. --package=foo
bekommen wir so den Wert foo
heraus.
Mehr Infos zu String Manipulationen, gibt es hier: https://www.tldp.org/LDP/abs/html/string-manipulation.html
Das Format der Argumente
Ich orientiere mich hier am POSIX Standard mit der GNU Erweiterung für lange Argumente. Das bedeutet folgende Varianten sind valide:
-h
--help
-p foo
--package=foo
Dinge wie -hv
(zusammengesetzt aus -h
und -v
) oder -pfoo
(als Äquivalent für -p foo
) beachte ich der Einfachheitshalber nicht.
Einfaches Beispiel
Ein funktionierendes Bash-Script findest du hier: https://gist.github.com/hauke96/2e8c8630906bc5253c84ed83751e045b
Viele nutzen eine while-Schleife und shiften sehr viel. Ich finde das unpraktisch und nutze daher die for-Schleife um einen Index zu haben. Wenn ein kurzes Argument (also z.B. -p foo
), was durch Leerzeichen getrennt ist, erkannt wurde, muss $i
manuell inkrementiert werden. Dadurch wird als nächstes nicht foo
, sondern das tatsächliche Argument danach behandelt.
Beispiel mit Befehlen
Befehle sind quasi eigene Unterprogramme und können eigene Argumente akzeptieren. Zum Beispiel akzeptiert apt-get install ...
eine Liste von Paketnamen, apt-get update
erlaubt keine weiteren Argumente.
Ein funktionierendes Bash-Script findest du hier: https://gist.github.com/hauke96/d069bcf32ec35c66412e9ee50b0295a8
Das Format, was ich nutze ist bash command.sh <COMMAND> <ARGUMENTS>
Zunächst hole ich mit arg=${@:1:1}
das erste Argument, was im Format oben <COMMAND>
entspricht. Das einzige erlaubte command ist hier einfach nur install
.
Da einzelne Kommandos entsprechend eigene Argumente haben können, werden diese in der parse_install_args
Funktion direkt weiterverarbeitet. Das sieht dann fast so aus, wie im einfachen Beispiel.
Alternativen
Wie schon erwähnt nutzen viele die while-Schleife. Sonstige Implementationen findet man genug auf z.B. Stackoverflow.
Pingback: CLI-Argumente in Bash-Scripten parsen – [curi0sity] | Mobilapka.cloud