Bash: Funktionen
Eine Funktion ist ein Unterprogramm, das über seinen Namen aufgerufen werden kann. Es können Daten an eine Funktion übergeben werden, die dort verarbeitet werden. Funktionen können einen Rückgabewert haben. Der Nutzen einer Funktion besteht vor allem darin, dass Code-Abschnitte, die häufiger zur Anwendung kommen, nicht immer wieder neu notiert werden müssen, sondern quasi in die Funktion ausgelagert werden. Dies erhöht die Übersichtlichkeit und Wartbarkeit des Codes.
Eine Funktion wird mit dem Schlüsselwort function definiert (eine alternative Notation wird im nächsten Abschnitt verwendet) und muss definiert werden, bevor sie aufgerufen werden kann. Für den Namen einer Funktion können nahezu alle druckbaren Zeichen in beliebiger Reihenfolge verwendet werden (hier: +0,ἀταραξία). Allerdings sollten bereits existierende Bash-Schlüsselwörter und Shell-Kommandos als Name vermieden werden, um Kollisionen zu vermeiden. Namen wie a=5 usw. können ebenfalls nicht verwendet werden.
In geschweiften Klammern {} steht dann der von der Funktion auszuführende Code-Block.
function +0,ἀταραξία {
echo "In der Funktion:"
echo "$a"
b=Bar
local c=Donk # nur innerhalb der Funktion gültig
echo "$c"
}
a=Foo
c=Bork
+0,ἀταραξία # Aufruf der Funktion
echo "Nach dem Aufruf der Funktion:"
echo "b = $b"
echo "c = $c" # bleibt durch die Funktion unverändert
Wie das Beispiel zeigt, sind Variablen aus dem normalen Programmfluss auch innerhalb von Funktionen gültig, selbst wenn die Variablen nicht explizit an die Funktion übergeben wurden (hier Variable a). Ebenso sind Variablen, die innerhalb einer Funktion definiert wurden, nach einem Funktionsaufruf auch im normalen Programmfluss verfügbar (hier Variable b), sofern sie nicht mit dem Kommando local definiert wurden, wodurch sie nur innerhalb der Funktion verfügbar sind (hier Variable c).
Dies gilt allerdings nicht, wenn eine Funktion mit der Konstruktion $(FUNKTION) als Kommando-Expansion aufgerufen wird (s. unten). In diesem Fall sind alle Variablen innerhalb der Funktion auch lokal.
Argumente an eine Funktion übergeben
Funktionen können ebenso wie Shell-Skripte selbst mit Argumenten aufgerufen werden, die dann innerhalb der Funktion ausgewertet werden können.
function machwas {
for arg in "${@}"; do # gibt die Argument einzeln aus
echo $arg
done
echo "---"
for arg; do # gibt die Argument ebenfalls einzeln aus
echo $arg
done
echo "---"
x="${1}" # das erste Argument
echo $x
}
machwas "Hallo, Welt!" 42 "" Bork # Funktionsaufruf mit vier Argumenten
Funktionen mit Rückgabewert
Wie wir im vorletzten Abschnitt gesehen haben, sind Variablen, die nicht mit local definiert wurden, sowohl innerhalb als auch außerhalb von Funktionen verfügbar, weshalb es in Bash nicht notwendig ist, Daten explizit an eine Funktion zu übergeben und einen Rückgabewert zu erzeugen.
rechnen() {
foo=$(($a + $b))
}
a=20
b=4
rechnen
echo "$a + $b = ${foo}"
Möchte man dies dennoch explizit tun, wie das in anderen Programmiersprachen meist üblich ist, so kann man folgendermaßen vorgehen. Bash kennt zwar das Schlüsselwort return, es hat hier aber eine andere Funktion als in anderen Programmiersprachen, wo es dazu dient, das Ergebnis einer Funktion an die aufrufenden Anweisung zurückzugeben. In Bash kann damit lediglich der Return-Code einer Funktion zurückgegeben werden, der einen Wert von 0 bis 255 annehmen kann. Dieser Wert kann unabhängig vom eigentlichen Ergebnis der Funktion ausgewertet werden.
Das folgenden Beispiel verdeutlicht, wie man sich dennoch behelfen kann. Die Konstruktion in Zeile 9 (Kommando-Expansion) weist die Bash dazu an, die Ausgabe der Funktion nicht am Bildschirm darzustellen (stdout), sondern in die Variable foo umzuleiten. Mit dem Operator $? wird in Zeile 10 der Return-Code der Funktion angezeigt, genauer gesagt, der letzten aufgerufenen Anweisung, wie Zeile 12 demonstriert.
rechnen() {
local a=$((${1} + ${2}))
echo $a
return 255 # Zahl zwischen 0 und 255 (letzte Anweisung)
}
a=20
b=4
foo="$(rechnen $a $b)"
echo $? # Rückgabewert der letzten Anweisung (255)
echo "$a + $b = ${foo}"
echo $? # Rückgabewert der letzten Anweisung (0)
Möchte man mehrere Werte zurückgeben, so schreibt man sie einfach in einen entsprechenden String, hier mit Leerzeichen voneinander getrennt (Zeile 6). In Zeile 11 wird der zurückgegebene String an den Leerzeichen in seine Bestandteile aufgetrennt und die gefundenen Elemente als Array in die Variable foo geschrieben. Anschließend können die Elemente so individuell weiterverarbeitet werden.
rechnen() {
local a=$((${1} + ${2}))
local s=$((${1} - ${2}))
local m=$((${1} * ${2}))
local d=$((${1} / ${2}))
echo $a $s $m $d
}
a=20
b=4
read -ra foo <<< "$(rechnen $a $b)" # liest die Einzelwerte in das Array foo
echo "$a + $b = ${foo[0]}"
echo "$a - $b = ${foo[1]}"
echo "$a * $b = ${foo[2]}"
echo "$a / $b = ${foo[3]}"
Rekursive Funktionen
Rekursive Funktionen sind Funktionen, die sich selbst aufrufen. Ein Beispiel dazu befindet sich im Artikel „Ordner und Dateien“.