getopts – Skript-Parameter, die sich wie richtige Befehle anfühlen
$1, $2, $3 funktioniert genau so lange, bis man einen Parameter weglassen will. Mit getopts bekommt dein Skript benannte Optionen, eine Hilfe und eine klare Fehlermeldung – in fünfzehn Zeilen.
Jedes Skript fängt so an:
ZIEL="$1"
ANZAHL="$2"Und dann kommt der Tag, an dem man $2 weglassen möchte, aber $3 braucht. Oder man ruft das Skript nach drei Monaten wieder auf und weiß nicht mehr, in welcher Reihenfolge die Argumente kamen. Ab da lohnt getopts.
Das Grundgerüst
#!/usr/bin/env bash
set -euo pipefail
ziel=""
anzahl=10
ausfuehrlich=0
hilfe() {
cat <<EOF
Verwendung: ${0##*/} -z ZIEL [-n ANZAHL] [-v]
-z ZIEL Zielordner (Pflicht)
-n ANZAHL Anzahl der Einträge (Standard: $anzahl)
-v ausführliche Ausgabe
-h diese Hilfe
EOF
}
while getopts ":z:n:vh" opt; do
case "$opt" in
z) ziel="$OPTARG" ;;
n) anzahl="$OPTARG" ;;
v) ausfuehrlich=1 ;;
h) hilfe; exit 0 ;;
:) echo "Option -$OPTARG braucht einen Wert." >&2; exit 2 ;;
\?) echo "Unbekannte Option: -$OPTARG" >&2; hilfe >&2; exit 2 ;;
esac
done
shift $((OPTIND - 1)) # verbrauchte Optionen wegräumen
[[ -n "$ziel" ]] || { echo "Fehler: -z fehlt." >&2; hilfe >&2; exit 2; }Ab hier hat dein Skript alles, was man von einem ordentlichen Befehl erwartet: benannte Optionen in beliebiger Reihenfolge, Standardwerte, eine Hilfe und verständliche Fehlermeldungen.
Die drei Zeichen, die man kennen muss
- Der Doppelpunkt nach einem Buchstaben (
z:) heißt: Diese Option braucht einen Wert. Ohne Doppelpunkt ist es ein reiner Schalter. - Der Doppelpunkt ganz vorne (
":z:n:vh") schaltet in den stillen Modus. Ohne ihn gibt Bash selbst eine englische Fehlermeldung aus, und der:-Zweig wird nie erreicht. Deine eigenen, deutschen Meldungen greifen erst mit diesem führenden Doppelpunkt. shift $((OPTIND - 1))entfernt alles, wasgetoptsverarbeitet hat. Danach stehen in$@nur noch die übrigen Argumente — praktisch, wenn dein Skript zusätzlich Dateinamen entgegennimmt.
Standardwerte richtig setzen
Die Zuweisung vor der Schleife ist der Standardwert; die Option überschreibt ihn nur, wenn sie angegeben wurde. Das ist der Grund, warum anzahl=10 oben steht und nicht irgendwo im case.
Wenn ein Wert auch aus der Umgebung kommen darf:
ziel="${ZIEL:-}" # nimmt $ZIEL, sonst leer
anzahl="${ANZAHL:-10}" # nimmt $ANZAHL, sonst 10Danach kann die Option beides überschreiben. Diese Reihenfolge — Standard, dann Umgebung, dann Option — ist die, die Nutzer erwarten.
Was getopts nicht kann
Lange Optionen wie --ziel=/pfad beherrscht es nicht. Dafür bräuchte man getopt (ohne s, ein eigenes Programm) oder eine eigene while-Schleife über $@. Ich verzichte darauf: Kurze Optionen plus eine gute -h-Hilfe reichen für eigene Werkzeuge völlig, und getopts ist überall vorhanden, ohne Sonderfälle zwischen Linux und macOS.
Warum sich das lohnt
Ein Skript mit -h ist ein Skript, das man in sechs Monaten noch benutzen kann. Ohne muss man den Quelltext lesen, um herauszufinden, was $3 eigentlich war. Die fünfzehn Zeilen oben sind bei mir inzwischen eine Vorlage, die ich in jedes neue Wartungsskript kopiere — und sie haben sich schon oft ausgezahlt.
Du hast Skripte auf deinem Server, die nur noch eine Person bedienen kann? Das lässt sich meist mit wenig Aufwand ändern. Melde dich.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Suchen & Ersetzen im Terminal mit sed
Einen Text in vielen Dateien austauschen, ohne jede von Hand zu öffnen – das erledigt sed in einer Zeile. Ich zeige dir das Grundmuster, wie du es sicher in mehreren Dateien anwendest und warum du vorher immer erst ohne -i testest.
Dateirechte verstehen – was 755 und 644 wirklich bedeuten
chmod 777 löst jedes Rechteproblem – und schafft ein größeres. Die drei Ziffern sind kein Zauberspruch, sondern eine simple Addition. Wer sie einmal verstanden hat, rät nie wieder.
cron – Aufgaben, die von selbst laufen (und warum sie es oft nicht tun)
Nächtliches Backup, wöchentlicher Bericht, stündliche Bereinigung: Fünf Zahlen und ein Befehl reichen. Der häufigste Fehler ist dabei nicht die Zeitangabe, sondern eine Umgebung, die ganz anders aussieht als dein Terminal.