CLI-Argumente in Bash-Scripten parsen

Facebooktwitterredditpinterestlinkedinmail
Argumente zu parsen ist nicht schwer. Auch nicht in Bash-Scripten.

Argumente zu parsen ist nicht schwer. Auch nicht in Bash-Scripten.

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.

Facebooktwitterredditpinterestlinkedinmail

1 Kommentar

  1. Pingback: CLI-Argumente in Bash-Scripten parsen – [curi0sity] | Mobilapka.cloud

Schreiben Sie einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert