Skripte und Funktionen sind erst dann nützlich, wenn sie beim Aufruf manipuliert und mit Daten bestückt werden können. Je nach Ansatz gelingt das mit mehr oder weniger Aufwand und Komfort.
Beim Bash-Scripting gibt es die Möglichkeit, Parameter über benannte Optionen zu übergeben.
Auch Entwickler entwickeln sich und beim Scripting in der Bash geht der Weg oft von simplen Aliasen über deren komplexe Vertreter und simple Funktionen bis hin zu ausführlichen Skripten. Allen gemein: Ohne die Möglichkeit, beim Aufruf weitere Daten oder Anweisungen übergeben zu können, bleiben es im Grunde schlichte Shortcuts, die ein wenig Tippaufwand einsparen.
Das klingt für Sie nach dem eigentlichen Einsatzzweck eines Alias? Bingo – und darum sind Aliase auch nicht für die Aufnahme von Parametern ausgelegt. Freilich lässt sich das bewerkstelligen, aber selbst die Bash selbst empfiehlt generell, Funktionen anstelle von Aliasen zu nutzen. Auch wenn es Dinge gibt, die sich tatsächlich besser per Alias lösen lassen.
Funktionen und Skripte hingegen sind dafür gedacht, mehr oder weniger komplexe Aufgaben für unterschiedliche Daten und mit unterschiedlichen Ausprägungen zu erledigen. In der Bash lassen sich an beide Varianten gleichermaßen Argumente, Optionen, Parameter übergeben – was zunächst die Frage nach dem Unterschied aufwirft.
Im Grunde ist das Wording recht simpel, wie das Beispiel „echo -e foobar“ zeigt: Jedes der drei Elemente ist im Shell-Sinne ein Argument. Das Argument „echo“ ist das eigentliche Kommando, das Argument „-e“ ist eine benannte, dokumentierte Option zum Modifizieren des Kommandos und das Argument „foobar“ ist der dem Kommando übergebene Parameter. Parameter sind also in der Regel die eigentlichen Daten, die jeder Nutzer individuell übergibt. Optionen hingegen sind im Kommando festgelegte Schalter, die vom Nutzer mit Parametern versorgt werden.
Eigentlich ist das alles logisch, nahezu intuitiv, aber im Detail – nun, nicht ohne Grund gibt es auf Stack Overflow dazu Dutzende Fragen mit Millionen Aufrufen. Zumal sich der Einsatz von Parametern in der Praxis meist ebenfalls entwickelt: Von schlicht durchnummerierten Parametern (Positional Parameters) über deren manuelle Benennung bis hin zur Zuordnung zu benannten Optionen mit dem Bash- und sh-internen Tool „getopts“ (nicht zu verwechseln mit dem älteren Stand-Alone-Programm „getopt“). Aber der Reihe nach, wortwörtlich.
Positional Parameters
Parameter können in der Bash ohne jegliche Angaben an Skripte und Funktionen übergeben werden – sie werden schlicht durchnummeriert und landen in den Variablen $1, $2, $3 und so weiter. Zur Demonstration soll das denkbar einfachste Beispiel dienen, eine Funktion „printit“:
printit () { echo Parameter 1 ist $1 echo Parameter 2 ist $2 }
Der Aufruf …
printit eins zwei
… produziert entsprechend:
Parameter 1 ist eins Parameter 2 ist zwei
Zusätzlich zu den durchnummerierten Parametern gibt es noch ein paar spezielle Variablen: „$#“ steht beispielsweise für die Anzahl der übergebenen Parameter, „$?“ für den Exit-Code, „$*“ und „$@“ zeigen alle Parameter als einen String beziehungsweise als einzelne Strings und „$0“ beinhaltet den Namen des aufgerufenen Skripts oder im Falle von Funktionen der aufrufenden Shell.
Um sich damit etwas näher vertraut zu machen, ließe sich die obige Funktion zu einer Hilfsfunktion erweitern:
printit () { echo Parameter 1 ist $1 echo Parameter 2 ist $2 echo "@" steht für $@ echo "*" steht für $* echo "#" steht für $# echo "?" steht für $? echo "0" steht für $0 }
Die Ausgabe ist entsprechend:
Parameter 1 ist eins Parameter 2 ist zwei @ steht für eins zwei * steht für eins zwei # steht für 2 ? steht für 0 0 steht für /usr/bin/bash
Und hier lauert mal wieder eine kleine Anführungszeichen-Hölle: Man beachte, dass die Ausgaben von $@ und $* identisch sind – das gilt aber nur, solange zwei Bedingungen erfüllt sind: Die Variablen stehen nicht in Anführungszeichen und der interne Wort-Separator (Internal Field Seperator/IFS) wurde nicht verändert. Hier nun die Ausgaben mit Anführungszeichen und dem Doppelpunkt als IFS:
printit () { IFS=: echo "@" steht für $@ echo "*" steht für $* }
„printit eins zwei“ ergibt dann:
@ steht für eins zwei * steht für eins:zwei
Man muss an dieser Stelle also umsichtig sein und prüfen, welche Variante tatsächlich benötigt wird. @ versteht alle Argumente separat, das * versteht alle Argumente als einen einzigen String.
Parameter nach Positionen sind einfach, bequem und manchmal sogar ausreichend. Aber natürlich sind Variablen wie „$Vorname“ und „$Nachname“ wesentlich verständlicher als schlicht ein paar Ziffern. Der logische Folgeschritt besteht im manuellen Umbenennen in der Art:
vorname="$1" nachname="$2"
Innerhalb von Skripten und Funktionen sieht es damit schon deutlich aufgeräumter aus. Vor allem aber: Parameter via Ziffern versteht bestenfalls der jeweilige Autor einer Funktion ohne Probleme – und spätestens bei ein paar Dutzend Zeilen und einem halben Dutzend Parametern auch dieser nicht mehr.
Zudem handelt es sich hier bislang um frei definierbare Parameter. Was aber, wenn die Ausgabe von Namen in einem anderen Format erfolgen soll? Oder wahlweise rückwärts? Natürlich könnte man selbst dann noch positionale Parameter nutzen – mal als Dummy-Beispiel:
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel IT-Medien GmbH, Max-Josef-Metzger-Straße 21, 86157 Augsburg, einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von Newslettern und Werbung nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung.
printname Peter Schmidt r c
Wenn der gewünschte Output hier „Schmidt, Peter“ wäre, könnten r und c entsprechend für das Komma und die gedrehte Schreibweise stehen – wenn man zum Beispiel via if-Abfragen nach r und c an den Positionen 3 und 4 fahndet. Das ist aber nicht bloß kompliziert, es geht auch garantiert schief. Sei es, weil jemand Marie Luise Müller heißt oder Parameter versehentlich an der falschen Stelle stehen. Die Lösung besteht darin, Parameter über benannte Optionen zu übergeben.
Optionen mit getopts
Das Bash-interne getopts löst aber nicht bloß das Problem der Übersichtlichkeit, sondern spendiert der Parameterübergabe generell mehr Komfort. So spielt etwa die Reihenfolge der Optionen keine Rolle, Parameter können für Optionen verpflichtend sein, es gibt eine gewisse Fehlerbehandlung und so weiter.
Getopts liest nacheinander jede gegebene Option ein und speichert eventuell zugehörige Parameter in der Variablen „$OPTARG“. Diese werden dann üblicherweise über ein CASE-Statement innerhalb einer WHILE-Schleife verarbeitet. Statt eines abstrakten, generischen Beispiels, soll es hier ein Mini-Skript mit folgender Funktion veranschaulichen: Das Skript gibt Vorname, Mittelname und Nachname als Liste sowie – optional – eine kurze Variante in der Form „Nachname, Vorname“ aus.
Zunächst das kleine Skript „printname.sh“, der Übersicht halber mit nummerierten Zeilen:
1 #!/bin/bash 2 3 while getopts "f:m:l:r" option 4 do 5 case $option in 6 f) firstname="$OPTARG";; 7 m) middlename="$OPTARG";; 8 l) lastname="$OPTARG";; 9 r) reverse=1;; 14 esac 15 done 16 17 echo Vorname: "$firstname" 18 echo Zweitname: "$middlename" 19 echo Nachname: "$lastname" 20 21 if [[ reverse -eq 1 ]]; then echo Reverse: "$lastname", "$firstname"; fi
In Zeile 3 werden die verfügbaren Optionen aufgelistet: „fml“ stehen hier für First-, middle und Lastname, „r“ steht für die Rückwärtsschreibweise „Nachname, Vorname“. Wichtig sind die Doppelpunkte: Ein Doppelpunkt nach einem Optionsbuchstaben besagt, dass diese Option einen Parameter benötigt – in diesem Fall also den jeweilen Namenspart. Gespeichert werden die Optionen/Parameter hier jeweils in der Variablen „option“, die Sie aber beliebig nennen können.
Die while-Schleife läuft also für jede gegebene Option einmal durch; das case-Statement ordnet die zur Option angegebenen Parameter/Werte wiederum sinnvoll benannten Variablen zu, hier eben „firstname“, „middlename“ und „lastname“.
Für die Option „r“ sieht es minimal anders aus: Hier wird kein Parameter übergeben, sondern stattdessen einfach eine Variable „reverse“ auf 1 gesetzt – da es sich hier um eine Option nach dem üblichen Verständnis handelt; einen Schalter, der den Programmablauf verändert, hier also eine zusätzliche Aktion durchführt.
Nach der while-Schleife folgt dann das eigentliche Skript, hier die simple, formatierte Ausgabe der übergebenen Daten in Listen- und Rückwärtsform.
Der Aufruf des Skripts …
printname.sh -l Müller -f Thomas -m J. -r
… erzeugt die Ausgabe:
Vorname: Thomas Zweitname: J. Nachname Müller Reverse: Müller, Thomas
Sie sehen hier schon: Die Reihenfolge der Optionen spielt keine Rolle.
Es gibt aber noch einen relevanten Doppelpunkt, der hier im Skript nicht vorkommt: Wenn im getopts-Statement ein solcher am Anfang der Optionen (vor dem f) steht, also …
getopts ":f:m:l:r"
…, unterdrückt getopts etwaige Fehlermeldungen – also zum Beispiel fehlende Parameter für Optionen oder ungültige Optionen. In der Praxis wird dieser führende Doppelpunkt häufig gesetzt, um eine eigene Fehlerbehandlung umzusetzen. Im case-Statement könnte das etwa so aussehen:
Das Fragezeichen greift nicht definierte Optionen ab, der Doppelpunkt fehlende Parameter für Optionen, die im getopts-Statement einen Doppelpunkt haben.
Und noch eine Zeile wird Ihnen im case-Statement häufig begegnen:
… h|*) echo $usage …
Das Sternchen fängt beide Fehlerarten (? und :) von oben ab und „h“ steht freilich wie üblich für einen Hilferuf – sprich: Werden falsche Optionen übergeben oder erforderliche Parameter für Optionen nicht übergeben, wird die Hilfe ($usage) angezeigt. Oder eben, wenn „-h“ als Option direkt aufgerufen wird.
Mit diesen Snippets können Sie sich durchaus ein brauchbares Template für Ihre Skripte und Funktionen zusammenbauen. Eine nicht ganz unerhebliche „Kleinigkeit“ sollte aber noch erwähnt werden. Mal angenommen, der Aufruf erfolgt so:
printname.sh -f -l
Man könnte nun annehmen, getopts würde eine Fehlermeldung ausgeben, weil die Optionen f und l ohne weitere Parameter gesetzt wurden. Stimmt aber natürlich nicht, hier würde „-l“ als Parameter für die f-Option interpretiert! Eine weitere Verfeinerung und Überprüfung, wie das Auschließen von Parametern, die mit „-“ beginnen oder bestimmte Format-Erfordernisse, müssen Sie manuell erledigen.
Eine letzte Frage dürfte fast immer aufkommen: Wie lassen sich Optionen als „zwingend nötig“ (mandatory) festlegen? Ganz klar: Gar nicht – Optionen sind naturgemäß optional … Auch an dieser Stelle müssten Sie manuell tätig werden und schlicht prüfen, ob die gewünschten Variablen nach Durchlauf der while-Schleife gesetzt sind oder nicht.
Müssen hier im Beispiel also Vor- und Nachname vorhanden sein, würde sich folgende Erweiterung des Skripts anbieten:
if [ ! "$firstname" ] || [ ! "$lastname" ]; then echo "Die Optionen -f und -l müssen gesetzt werden!" & exit 1 fi
Es lohnt sich durchaus, getopts auch bei kleineren Skripten von Beginn an einzusetzen, schließlich neigen Skripte dazu, im Laufe der Zeit zu wachsen. Mit einer persönlichen getopts-Vorlage ist der Aufwand minimal, eine nachträgliche Migration allerdings garantiert nicht unproblematisch.