694 lines
12 KiB
Markdown
694 lines
12 KiB
Markdown
# BASH Funktionen# BASH FunktionenIn **[[Bash]]** kannst du wiederverwendbare **Funktionen** definieren, um Code übersichtlicher und modularer zu gestalten.
|
||
|
||
|
||
|
||
In BASH kannst du wiederverwendbare Funktionen definieren, um Code übersichtlicher und modularer zu gestalten.Hier ist eine kurze Einführung mit Beispielen 👇
|
||
|
||
|
||
|
||
## GrundsyntaxIn BASH kannst du wiederverwendbare Funktionen definieren, um Code übersichtlicher und modularer zu gestalten.
|
||
|
||
|
||
|
||
```bash---
|
||
|
||
meine_funktion() {
|
||
|
||
echo "Das ist eine wiederverwendbare Funktion!"## Grundsyntax
|
||
|
||
}
|
||
|
||
```### 🔹 **Grundsyntax einer Funktion**
|
||
|
||
|
||
|
||
Alternative Syntax (weniger üblich):```bash
|
||
|
||
|
||
|
||
```bashmeine_funktion() {```bash
|
||
|
||
function meine_funktion {
|
||
|
||
echo "Das ist eine wiederverwendbare Funktion!" echo "Das ist eine wiederverwendbare Funktion!"meine_funktion() {
|
||
|
||
}
|
||
|
||
```} echo "Das ist eine wiederverwendbare Funktion!"
|
||
|
||
|
||
|
||
## Funktion mit Parametern```}
|
||
|
||
|
||
|
||
In BASH werden Argumente positional übergeben: `$1`, `$2`, usw.```
|
||
|
||
|
||
|
||
```bashAlternative Syntax (weniger üblich):
|
||
|
||
begruesse() {
|
||
|
||
echo "Hallo $1!"Oder alternativ (weniger üblich, aber erlaubt):
|
||
|
||
}
|
||
|
||
```bash
|
||
|
||
begruesse "Anna"
|
||
|
||
# Ausgabe: Hallo Anna!function meine_funktion {```bash
|
||
|
||
```
|
||
|
||
echo "Das ist eine wiederverwendbare Funktion!"function meine_funktion {
|
||
|
||
## Rückgabewerte
|
||
|
||
} echo "Das ist eine wiederverwendbare Funktion!"
|
||
|
||
### Numerischer Exit-Code
|
||
|
||
```}
|
||
|
||
Eine Funktion kann mit `return` einen numerischen Exit-Code (0–255) zurückgeben:
|
||
|
||
```
|
||
|
||
```bash
|
||
|
||
teste_zahl() {## Funktion mit Parametern
|
||
|
||
if (( $1 > 10 )); then
|
||
|
||
return 0 # Erfolg---
|
||
|
||
else
|
||
|
||
return 1 # FehlerIn BASH werden Argumente positional übergeben: `$1`, `$2`, usw.
|
||
|
||
fi
|
||
|
||
}### 🔹 **Funktion mit Parametern**
|
||
|
||
|
||
|
||
if teste_zahl 15; then```bash
|
||
|
||
echo "Größer als 10"
|
||
|
||
elsebegruesse() {In Bash werden Argumente **positional** übergeben — also `$1`, `$2`, usw.
|
||
|
||
echo "Nicht größer als 10"
|
||
|
||
fi echo "Hallo $1!"
|
||
|
||
```
|
||
|
||
}```bash
|
||
|
||
### Text zurückgeben
|
||
|
||
begruesse() {
|
||
|
||
Um Text zurückzugeben, verwende `echo` oder `printf` und Command Substitution:
|
||
|
||
begruesse "Anna" echo "Hallo $1!"
|
||
|
||
```bash
|
||
|
||
addiere() {# Ausgabe: Hallo Anna!}
|
||
|
||
echo $(( $1 + $2 ))
|
||
|
||
}```
|
||
|
||
|
||
|
||
summe=$(addiere 3 5)begruesse "Anna"
|
||
|
||
echo "Summe: $summe" # Ausgabe: Summe: 8
|
||
|
||
```## Rückgabewerte# Ausgabe: Hallo Anna!
|
||
|
||
|
||
|
||
## Funktionen wiederverwendbar machen```
|
||
|
||
|
||
|
||
Speichere Funktionen in einer separaten Datei und lade sie mit `source`:### Numerischer Exit-Code
|
||
|
||
|
||
|
||
**funktionen.sh:**---
|
||
|
||
```bash
|
||
|
||
#!/bin/bashEine Funktion kann mit `return` einen numerischen Exit-Code (0–255) zurückgeben:
|
||
|
||
begruesse() {
|
||
|
||
echo "Hallo $1!"### 🔹 **Rückgabewerte**
|
||
|
||
}
|
||
|
||
``````bash
|
||
|
||
|
||
|
||
**hauptskript.sh:**teste_zahl() {- Eine Funktion kann mit `return` einen **numerischen Exit-Code** (0–255) zurückgeben.
|
||
|
||
```bash
|
||
|
||
#!/bin/bash if (( $1 > 10 )); then
|
||
|
||
source ./funktionen.sh
|
||
|
||
return 0 # Erfolg- Um Text zurückzugeben, verwendest du **`echo`** oder **`printf`** und fängst den Wert mit **Command Substitution** ein.
|
||
|
||
begruesse "Welt"
|
||
|
||
``` else
|
||
|
||
|
||
|
||
Alternative: `. ./funktionen.sh` return 1 # Fehler
|
||
|
||
|
||
|
||
## Lokale Variablen fi```bash
|
||
|
||
|
||
|
||
Verwende `local`, um Variablen nur innerhalb der Funktion sichtbar zu machen:}# numerischer Rückgabewert
|
||
|
||
|
||
|
||
```bashteste_zahl() {
|
||
|
||
addiere() {
|
||
|
||
local summe=$(( $1 + $2 ))if teste_zahl 15; then if (( $1 > 10 )); then
|
||
|
||
echo "$summe"
|
||
|
||
} echo "Größer als 10" return 0 # Erfolg
|
||
|
||
```
|
||
|
||
else else
|
||
|
||
## Default-Werte für Parameter
|
||
|
||
echo "Nicht größer als 10" return 1 # Fehler
|
||
|
||
```bash
|
||
|
||
mein_script() {fi fi
|
||
|
||
local name="${1:-Welt}" # Standardwert 'Welt'
|
||
|
||
local sprache="${2:-de}" # Standardwert 'de'```}
|
||
|
||
|
||
|
||
echo "Name: $name, Sprache: $sprache"
|
||
|
||
}
|
||
|
||
### Text zurückgebenif teste_zahl 15; then
|
||
|
||
mein_script "Anna" "en" # Name: Anna, Sprache: en
|
||
|
||
mein_script "Bob" # Name: Bob, Sprache: de echo "Größer als 10"
|
||
|
||
```
|
||
|
||
Um Text zurückzugeben, verwende `echo` oder `printf` und Command Substitution:else
|
||
|
||
## Benannte Argumente simulieren
|
||
|
||
echo "Nicht größer als 10"
|
||
|
||
### Mit case und Schleife
|
||
|
||
```bashfi
|
||
|
||
```bash
|
||
|
||
begruesse() {addiere() {```
|
||
|
||
local name="Welt"
|
||
|
||
local sprache="de" echo $(( $1 + $2 ))
|
||
|
||
|
||
|
||
for arg in "$@"; do}```bash
|
||
|
||
case $arg in
|
||
|
||
--name=*)# Text zurückgeben
|
||
|
||
name="${arg#*=}"
|
||
|
||
;;summe=$(addiere 3 5)addiere() {
|
||
|
||
--sprache=*|--lang=*)
|
||
|
||
sprache="${arg#*=}"echo "Summe: $summe" # Ausgabe: Summe: 8 echo $(( $1 + $2 ))
|
||
|
||
;;
|
||
|
||
*)```}
|
||
|
||
echo "Unbekannte Option: $arg" >&2
|
||
|
||
;;
|
||
|
||
esac
|
||
|
||
done## Funktionen wiederverwendbar machensumme=$(addiere 3 5)
|
||
|
||
|
||
|
||
echo "Hallo $name! (Sprache: $sprache)"echo "Summe: $summe"
|
||
|
||
}
|
||
|
||
Speichere Funktionen in einer separaten Datei und lade sie mit `source`:# Ausgabe: Summe: 8
|
||
|
||
begruesse --name=Anna --sprache=en
|
||
|
||
``````
|
||
|
||
|
||
|
||
**Vorteile:****funktionen.sh:**
|
||
|
||
- Reihenfolge der Argumente ist egal
|
||
|
||
- Default-Werte bleiben bestehen```bash---
|
||
|
||
- Sehr gut lesbar
|
||
|
||
#!/bin/bash
|
||
|
||
### Mit assoziativem Array
|
||
|
||
begruesse() {### 🔹 **Wiederverwendbar machen**
|
||
|
||
```bash
|
||
|
||
begruesse() { echo "Hallo $1!"
|
||
|
||
declare -A args=(
|
||
|
||
[name]="Welt"}Speichere deine Funktionen in einer separaten Datei, z. B. `funktionen.sh`, und **sourcen** sie in anderen Skripten:
|
||
|
||
[sprache]="de"
|
||
|
||
)```
|
||
|
||
|
||
|
||
for arg in "$@"; do**funktionen.sh**
|
||
|
||
[[ $arg == *=* ]] || continue
|
||
|
||
key="${arg%%=*}"**hauptskript.sh:**
|
||
|
||
val="${arg#*=}"
|
||
|
||
args[$key]="$val"```bash```bash
|
||
|
||
done
|
||
|
||
#!/bin/bash#!/bin/bash
|
||
|
||
echo "Hallo ${args[name]}! (Sprache: ${args[sprache]})"
|
||
|
||
}source ./funktionen.shbegruesse() {
|
||
|
||
|
||
|
||
begruesse name=Anna sprache=en echo "Hallo $1!"
|
||
|
||
```
|
||
|
||
begruesse "Welt"}
|
||
|
||
## Praktische Beispiele
|
||
|
||
``````
|
||
|
||
### Backup-Funktion
|
||
|
||
|
||
|
||
```bash
|
||
|
||
backup_datei() {Alternative: `. ./funktionen.sh`**hauptskript.sh**
|
||
|
||
local datei="$1"
|
||
|
||
local backup="${datei}.backup-$(date +%Y%m%d)"
|
||
|
||
|
||
|
||
if [[ -f "$datei" ]]; then## Lokale Variablen```bash
|
||
|
||
cp "$datei" "$backup"
|
||
|
||
echo "Backup erstellt: $backup"#!/bin/bash
|
||
|
||
else
|
||
|
||
echo "Fehler: $datei nicht gefunden" >&2Verwende `local`, um Variablen nur innerhalb der Funktion sichtbar zu machen:source ./funktionen.sh
|
||
|
||
return 1
|
||
|
||
fi
|
||
|
||
}
|
||
|
||
```bashbegruesse "Welt"
|
||
|
||
backup_datei wichtig.txt
|
||
|
||
```addiere() {```
|
||
|
||
|
||
|
||
### Fehlerbehandlung local summe=$(( $1 + $2 ))
|
||
|
||
|
||
|
||
```bash echo "$summe"Oder mit:
|
||
|
||
sicheres_loeschen() {
|
||
|
||
local datei="$1"}
|
||
|
||
|
||
|
||
if [[ ! -f "$datei" ]]; then``````bash
|
||
|
||
echo "Fehler: $datei existiert nicht" >&2
|
||
|
||
return 1. ./funktionen.sh
|
||
|
||
fi
|
||
|
||
## Default-Werte für Parameter```
|
||
|
||
read -p "Wirklich $datei löschen? (j/n) " antwort
|
||
|
||
if [[ "$antwort" == "j" ]]; then
|
||
|
||
rm "$datei"
|
||
|
||
echo "$datei gelöscht"```bash---
|
||
|
||
else
|
||
|
||
echo "Abgebrochen"mein_script() {
|
||
|
||
fi
|
||
|
||
} local name="${1:-Welt}" # Standardwert 'Welt'### 🔹 **Bonus: Funktionen mit lokaler Variable**
|
||
|
||
```
|
||
|
||
local sprache="${2:-de}" # Standardwert 'de'
|
||
|
||
### Mehrere Rückgabewerte
|
||
|
||
Verwende `local`, um Variablen nur innerhalb der Funktion sichtbar zu machen:
|
||
|
||
```bash
|
||
|
||
datei_info() { echo "Name: $name, Sprache: $sprache"
|
||
|
||
local datei="$1"
|
||
|
||
}```bash
|
||
|
||
if [[ -f "$datei" ]]; then
|
||
|
||
echo "$(wc -l < "$datei")" # Zeilenaddiere() {
|
||
|
||
echo "$(wc -w < "$datei")" # Wörter
|
||
|
||
echo "$(stat -c%s "$datei")" # Größemein_script "Anna" "en" # Name: Anna, Sprache: en local summe=$(( $1 + $2 ))
|
||
|
||
fi
|
||
|
||
}mein_script "Bob" # Name: Bob, Sprache: de echo "$summe"
|
||
|
||
|
||
|
||
# Verwendung```}
|
||
|
||
read zeilen woerter groesse <<< $(datei_info text.txt)
|
||
|
||
echo "Zeilen: $zeilen, Wörter: $woerter, Größe: $groesse"```
|
||
|
||
```
|
||
|
||
## Benannte Argumente simulieren
|
||
|
||
## Best Practices
|
||
|
||
---
|
||
|
||
### Eingabevalidierung
|
||
|
||
### Mit case und Schleife
|
||
|
||
```bash
|
||
|
||
verarbeite_zahl() {## 🧩 Beispiel 1: Named Arguments via `local` + Parameter Expansion
|
||
|
||
local zahl="$1"
|
||
|
||
```bash
|
||
|
||
if ! [[ "$zahl" =~ ^[0-9]+$ ]]; then
|
||
|
||
echo "Fehler: Keine gültige Zahl" >&2begruesse() {```bash
|
||
|
||
return 1
|
||
|
||
fi local name="Welt"mein_script() {
|
||
|
||
|
||
|
||
echo "Ergebnis: $((zahl * 2))" local sprache="de" local name="${1:-Welt}" # Standardwert 'Welt'
|
||
|
||
}
|
||
|
||
``` local sprache="${2:-de}" # Standardwert 'de'
|
||
|
||
|
||
|
||
### Dokumentation for arg in "$@"; do
|
||
|
||
|
||
|
||
```bash case $arg in echo "Name: $name"
|
||
|
||
# Berechnet die Summe zweier Zahlen
|
||
|
||
# Parameter: --name=*) echo "Sprache: $sprache"
|
||
|
||
# $1 - erste Zahl
|
||
|
||
# $2 - zweite Zahl name="${arg#*=}"}
|
||
|
||
# Rückgabe:
|
||
|
||
# Summe der beiden Zahlen ;;
|
||
|
||
addiere() {
|
||
|
||
echo $(( $1 + $2 )) --sprache=*|--lang=*)mein_script "Anna" "en"
|
||
|
||
}
|
||
|
||
``` sprache="${arg#*=}"mein_script "Bob"
|
||
|
||
|
||
|
||
### Fehler propagieren ;;```
|
||
|
||
|
||
|
||
```bash *)
|
||
|
||
hauptfunktion() {
|
||
|
||
hilfsfunktion || return $? echo "Unbekannte Option: $arg" >&2➡️ Ausgabe:
|
||
|
||
# Weiterer Code nur wenn hilfsfunktion erfolgreich
|
||
|
||
} ;;
|
||
|
||
```
|
||
|
||
esac```
|
||
|
||
## Siehe auch
|
||
|
||
doneName: Anna
|
||
|
||
- [[grep]] - Textsuche in Scripten
|
||
|
||
- [[sed]] - Textmanipulation in FunktionenSprache: en
|
||
|
||
- [[find]] - Dateien in Funktionen verarbeiten
|
||
|
||
echo "Hallo $name! (Sprache: $sprache)"Name: Bob
|
||
|
||
}Sprache: de
|
||
|
||
```
|
||
|
||
begruesse --name=Anna --sprache=en
|
||
|
||
```Aber das sind **positionsbasierte Argumente**, keine echten "benannten".
|
||
|
||
|
||
|
||
**Vorteile:**---
|
||
|
||
- Reihenfolge der Argumente ist egal
|
||
|
||
- Default-Werte bleiben bestehen## 🧩 Beispiel 2: Simulierte **benannte Argumente** mit `case` oder Schleife
|
||
|
||
- Sehr gut lesbar
|
||
|
||
Du kannst Argumente wie `--name=Anna` oder `--lang=en` verwenden:
|
||
|
||
### Mit assoziativem Array
|
||
|
||
```bash
|
||
|
||
```bashbegruesse() {
|
||
|
||
begruesse() { local name="Welt"
|
||
|
||
declare -A args=( local sprache="de"
|
||
|
||
[name]="Welt"
|
||
|
||
[sprache]="de" for arg in "$@"; do
|
||
|
||
) case $arg in
|
||
|
||
--name=*)
|
||
|
||
for arg in "$@"; do name="${arg#*=}"
|
||
|
||
[[ $arg == *=* ]] || continue ;;
|
||
|
||
key="${arg%%=*}" --sprache=*|--lang=*)
|
||
|
||
val="${arg#*=}" sprache="${arg#*=}"
|
||
|
||
args[$key]="$val" ;;
|
||
|
||
done *)
|
||
|
||
echo "Unbekannte Option: $arg" >&2
|
||
|
||
echo "Hallo ${args[name]}! (Sprache: ${args[sprache]})" ;;
|
||
|
||
} esac
|
||
|
||
done
|
||
|
||
begruesse name=Anna sprache=en
|
||
|
||
``` echo "Hallo $name! (Sprache: $sprache)"
|
||
|
||
}
|
||
|
||
## Siehe auch
|
||
|
||
begruesse --name=Anna --sprache=en
|
||
|
||
- [[find]] - BASH-Befehl zum Suchen von Dateienbegruesse
|
||
|
||
- [[grep]] - Textsuche in Dateien```
|
||
|
||
|
||
➡️ Ausgabe:
|
||
|
||
```
|
||
Hallo Anna! (Sprache: en)
|
||
Hallo Welt! (Sprache: de)
|
||
```
|
||
|
||
✅ Vorteil: Reihenfolge der Argumente ist egal
|
||
✅ Default-Werte bleiben bestehen
|
||
✅ Sehr gut lesbar
|
||
|
||
---
|
||
|
||
## 🧩 Beispiel 3: Named Args via **`declare -A` (assoziatives Array)**
|
||
|
||
Etwas fortgeschrittener, aber elegant:
|
||
|
||
```bash
|
||
begruesse() {
|
||
declare -A args=(
|
||
[name]="Welt"
|
||
[sprache]="de"
|
||
)
|
||
|
||
for arg in "$@"; do
|
||
[[ $arg == *=* ]] || continue
|
||
key="${arg%%=*}"
|
||
val="${arg#*=}"
|
||
args[$key]="$val"
|
||
done
|
||
|
||
echo "Hallo ${args[name]}! (Sprache: ${args[sprache]})"
|
||
}
|
||
|
||
begruesse name=Anna sprache=en
|
||
```
|
||
|
||
---
|
||
|
||
## 🧩 Beispiel 4: Default-Werte per `:`-Operator
|
||
|
||
Falls du Parameter ohne Parsing willst, kannst du Default-Werte einfach so setzen:
|
||
|
||
```bash
|
||
begruesse() {
|
||
local name="${1:-Welt}"
|
||
local sprache="${2:-de}"
|
||
|
||
echo "Hallo $name in Sprache $sprache"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 🔹 Empfehlung
|
||
|
||
Wenn du Funktionen **häufig wiederverwenden** oder **CLI-ähnliche Aufrufe** unterstützen willst, ist **Variante 2 (mit `--option=wert`)** am besten:
|
||
|
||
- Lesbar
|
||
|
||
- Robust
|
||
|
||
- Einfach erweiterbar
|
||
|
||
|
||
---
|