- 1 Section
- 10 Lessons
- unbegrenzt
- Bash / Shell-Scripting10
- 1.1Was ist eine Shell? bash, sh, zsh im Vergleich
- 1.2Grundlegende Befehle: cd, ls, cp, mv, rm, grep
- 1.3Variablen, Eingabe und Ausgabe
- 1.4Kontrollstrukturen: if, case, for, while
- 1.5Funktionen und Argumente
- 1.6Fehlerbehandlung: exit codes, trap
- 1.7Textverarbeitung: sed, awk, cut, sort
- 1.8Dateisystem-Automation: find, xargs, cron
- 1.9Netzwerk-Scripting: curl, ssh, rsync
- 1.10Praxisprojekt: Systemstatus- und Backup-Script
Funktionen und Argumente
Sobald deine Bash-Skripte mehr als 30-40 Zeilen haben, willst du sie strukturieren. Funktionen sind dafür das Werkzeug: wiederverwendbare Code-Blöcke mit Namen, die du beliebig oft aufrufen kannst. In Bash sind sie ähnlich konzipiert wie in Python, aber haben einige Eigenheiten – besonders bei Argumenten und Rückgabewerten.
Argumente werden in Bash nicht in Klammern übergeben sondern wie bei einem ganz normalen Befehl mit Leerzeichen getrennt. Und „Return-Werte" funktionieren ganz anders als in den meisten Sprachen – sie sind eigentlich Exit-Codes, nicht Datenrückgabe. Wer das verinnerlicht, schreibt sauberen modularen Bash-Code.
1) Eine Funktion definieren
Es gibt zwei Schreibweisen für Funktions-Definitionen. Beide funktionieren gleich – die erste ist POSIX-konform und portabel, die zweite mit function-Keyword ist Bash-spezifisch. Klicke die Teile an:
echo "Hallo, $1!"
}
begruesse "Anna"
2) Argumente – $1, $2, $@, $#
Bash hat speziell numerierte Variablen für Argumente. Sie funktionieren sowohl in Funktionen als auch im Skript-Hauptteil – aber jede Funktion hat ihre eigenen. Hier ein konkretes Beispiel: ein Aufruf backup quelle.txt zielordner/:
"$@" (mit Quotes) behält Wort-Grenzen bei – jedes Argument bleibt eins. $* oder "$*" fasst alle zu einem String zusammen. Faustregel: nimm fast immer "$@", das macht keine Überraschungen mit Leerzeichen. Funktionen können auch ihre Argumente an andere Funktionen weiterreichen: andereFunk "$@".3) Argumente in Funktionen vs. Skript-Argumente
Eine wichtige Subtilität: $1 bedeutet INNERHALB einer Funktion etwas anderes als außerhalb. Bash speichert die alten Werte auf einen Stack und stellt sie nach dem Funktionsaufruf wieder her:
Das ist auch der Grund warum Funktionen ihre Argumente nicht „automatisch" sehen. Wer in Python das umständlich findet, mag Bash hier sogar einfacher – aber man muss daran denken alle nötigen Werte zu übergeben.
4) Rückgabewerte – Bashs Eigenheiten
Hier wird's ungewöhnlich. Bash-Funktionen geben kein „Ergebnis" zurück wie eine Python-Funktion. Stattdessen gibt es drei Wege:
$? abgreifen.if [[ $EUID -eq 0 ]]; then
return 0 # Erfolg
else
return 1 # Fehlschlag
fi
}
if ist_root; then echo "ist root"; fi
$(...). Wie eine „normale" Funktion in anderen Sprachen.date +"%H:%M:%S"
}
zeit=$(aktuelle_uhrzeit)
echo "Jetzt: $zeit"
CONFIG_USER="anna" # globale Var
CONFIG_PORT=8080
}
parse_config
echo "User: $CONFIG_USER, Port: $CONFIG_PORT"
return "Anna", gibt's einen Fehler. Für echte Daten: Weg 2 (echo + $(...)) – das ist die häufigste Praxis. Wer aus Python kommt und schwer umdenkt: Bash ist nicht funktional aufgebaut, sondern stream-basiert. Funktionen schreiben Daten in Streams, Aufrufer fangen sie.5) Lokale Variablen mit local
Standardmäßig sind ALLE Variablen in Bash global – auch die in Funktionen. Das ist eine häufige Bug-Quelle. Mit local beschränkst du eine Variable auf die Funktion:
zaehle() {
for i in 1 2 3; do
echo "In Funk: $i"
done
}
zaehle
echo "Nach Funk: $i"
# → 3 (überschrieben!)
zaehle() {
local i
for i in 1 2 3; do
echo "In Funk: $i"
done
}
zaehle
echo "Nach Funk: $i"
# → 99 (unverändert)
local deklarieren. Spart später viele Stunden Debugging. Du kannst local auch direkt mit Wert kombinieren: local zaehler=0. Auch für Argumente lohnt es sich: local datei="$1" – macht den Code lesbarer und vermeidet versehentliches Überschreiben.6) Funktionen mit Optionen – getopts
Wenn deine Funktion oder dein Skript Optionen wie -v oder --verbose entgegennehmen soll, gibt es getopts für eine saubere Verarbeitung:
Die Optionen-String "vf:n:" heißt: erlaubt sind -v, -f mit Wert, -n mit Wert. Doppelpunkt nach Buchstabe = nimmt einen Wert entgegen. $OPTARG ist der Wert. Für die langen Optionen --verbose brauchst du getopt (ohne s, externes Programm) oder eine manuelle Schleife.
7) Funktionen mit Default-Werten
Bash hat keine eingebauten Default-Werte für Argumente wie Python. Workaround mit Parameter-Expansion (siehe L3):
8) Eine wiederverwendbare Helper-Funktion bauen
Ein praktisches Beispiel: eine Logging-Funktion die du in mehreren Skripten nutzt:
Solche Helper-Funktionen sammelt man oft in einer separaten Datei (z.B. helpers.sh) und lädt sie mit source helpers.sh oder kurz . helpers.sh ins Skript. So baut man sich über die Zeit eine eigene Mini-Bibliothek.
9) Rekursion in Bash
Funktionen können sich selbst aufrufen. Funktioniert genauso wie in anderen Sprachen – aber Bash ist nicht für Rekursion optimiert, vermeide tiefe Verschachtelung:
Für ernsthaft rekursive Algorithmen lieber zu Python greifen – Bash ist langsam bei vielen Funktionsaufrufen und der Stack ist limitiert.
10) Best Practices für Bash-Funktionen
Wenn du Funktionen so schreibst, danken dir Kollegen (und dein zukünftiges Ich):
- Aussagekräftige Namen in snake_case.
backup_datenbankstattbd. - local für alle internen Variablen – immer, ohne Ausnahme.
- Argumente direkt am Anfang in benannte Variablen:
local quelle="$1"; local ziel="$2". Lesbarer als$1überall. - Argument-Validierung mit if zu Beginn: „Wenn nicht genug Args, dann Fehlermeldung und exit".
- Kommentar über der Funktion: was macht sie, was erwartet sie, was gibt sie zurück.
- Eine Funktion = eine Aufgabe. Wenn sie 50+ Zeilen wird, in mehrere zerlegen.
- Exit-Code 0 bei Erfolg, ≠0 bei Fehler – Konvention die alle Unix-Tools nutzen.
Ein Beispiel mit allen Best Practices:
Zusammenfassung
Funktion definieren: name() { ... } oder function name() { ... }. Aufruf ohne Klammern: name arg1 arg2. Argumente: $1, $2, ... (in der Funktion!), $@ alle, $# Anzahl, "$@" mit Quotes ist sicherer. return nur für Exit-Codes 0-255 (NICHT für Daten). Daten zurückgeben: echo + $(funk) beim Aufruf. local var für lokale Variablen – sonst alles global! Default-Werte mit ${1:-"default"}. Optionen-Parsing mit getopts. Funktionen vor Aufruf definieren (Reihenfolge wichtig). Best Practices: aussagekräftige Namen, alle Variablen local, Args am Anfang in benannte Variablen, Validierung, Exit-Code 0/≠0.
