Bash Grundkurs #4: Funktionen in Bash

Willkommen zum vierten Artikel unserer technischen Wiki-Serie über Bash-Programmierung!

In den vorherigen Artikeln hast du gelernt, wie du Bash-Skripte erstellst, mit Variablen arbeitest und Kontrollstrukturen wie if-else und Schleifen verwendest. Heute machen wir den nächsten wichtigen Schritt: Wir lernen, wie du deinen Code in handliche Funktionen verpackst.

Was sind Funktionen?

Stell dir vor, du schreibst ein Skript, das mehrmals die gleiche Aufgabe ausführen soll – zum Beispiel eine Begrüßung ausgeben oder eine Berechnung durchführen. Anstatt den gleichen Code immer wieder zu schreiben, wäre es doch praktisch, wenn du ihn einmal schreiben und dann immer wieder verwenden könntest. Genau das ermöglichen dir Funktionen!

Eine Funktion ist wie ein kleines Unterprogramm in deinem Skript. Du gibst ihr einen Namen und kannst sie dann immer wieder aufrufen, wenn du sie brauchst. Das macht deinen Code:

  • übersichtlicher
  • leichter zu verstehen
  • einfacher zu warten
  • wiederverwendbar

Deine erste Funktion

Lass uns mit einer ganz einfachen Funktion beginnen:

Bash
#!/bin/bash

# Eine einfache Begrüßungsfunktion
begruessung() {
    echo "Hallo! Willkommen in der Welt der Bash-Funktionen!"
}

# So rufst du die Funktion auf
begruessung
Was passiert hier?
  1. Mit begruessung() geben wir der Funktion einen Namen
  2. Zwischen den geschweiften Klammern { } steht der Code der Funktion
  3. Mit begruessung (ohne Klammern) rufen wir die Funktion auf

Funktionen mit Parametern

Jetzt, wo du weißt, wie eine einfache Funktion aussieht, machen wir sie flexibler. Stell dir vor, du möchtest nicht nur „Hallo“ sagen, sondern jemanden mit Namen begrüßen.

Dafür kannst du deiner Funktion Parameter übergeben:

Bash
#!/bin/bash

# Funktion mit einem Parameter
persoenliche_begruessung() {
    echo "Hallo $1! Schön, dass du da bist!"
}

# Funktion aufrufen mit verschiedenen Namen
persoenliche_begruessung "Max"
persoenliche_begruessung "Anna"

Was ist neu?

  • $1 ist der erste Parameter, den die Funktion erhält
  • Beim Aufruf übergeben wir den Namen in Anführungszeichen
  • Die Funktion verwendet den übergebenen Namen in der Begrüßung

Lass uns das erweitern und mehrere Parameter verwenden:

Bash
#!/bin/bash

# Funktion mit zwei Parametern
benutzer_info() {
    echo "Name: $1"
    echo "Alter: $2"
}

# Funktion mit zwei Parametern aufrufen
benutzer_info "Max" "25"

Wichtig für Anfänger:

  • $1 ist der erste Parameter
  • $2 ist der zweite Parameter
  • Die Parameter werden durch Leerzeichen getrennt
  • Verwende Anführungszeichen bei Texten mit Leerzeichen

Parameter überprüfen

Wenn du Funktionen mit Parametern verwendest, ist es wichtig sicherzustellen, dass alle benötigten Parameter auch übergeben wurden.

Lass uns unsere vorherige Funktion sicherer machen:

Bash
#!/bin/bash

benutzer_info() {
    # Prüfen, ob beide Parameter vorhanden sind
    if [ $# -lt 2 ]; then
        echo "Fehler: Diese Funktion benötigt zwei Parameter"
        echo "Verwendung: benutzer_info NAME ALTER"
        return 1
    fi

    # Jetzt können wir sicher sein, dass beide Parameter da sind
    echo "Name: $1"
    echo "Alter: $2"
}

# Verschiedene Testaufrufe
benutzer_info "Max" "25"          # Funktioniert
benutzer_info "Anna"              # Fehler: zu wenige Parameter
benutzer_info                     # Fehler: keine Parameter

Was ist hier neu?

  • $# gibt die Anzahl der übergebenen Parameter an
  • [ $# -lt 2 ] prüft, ob weniger als 2 Parameter übergeben wurden
  • return 1 beendet die Funktion mit einem Fehlercode
  • Die Fehlermeldung zeigt, wie die Funktion richtig verwendet wird

Lass uns eine praktische Funktion erstellen, die auch prüft, ob die Eingaben sinnvoll sind:

Bash
#!/bin/bash

addiere_zahlen() {
    # Prüfe Anzahl der Parameter
    if [ $# -ne 2 ]; then
        echo "Fehler: Bitte gib genau zwei Zahlen ein"
        echo "Beispiel: addiere_zahlen 5 3"
        return 1
    fi

    # Prüfe, ob die Parameter Zahlen sind
    if ! [[ $1 =~ ^[0-9]+$ ]] || ! [[ $2 =~ ^[0-9]+$ ]]; then
        echo "Fehler: Bitte gib nur positive Ganzzahlen ein"
        return 1
    fi

    # Berechne und zeige das Ergebnis
    local summe=$(($1 + $2))
    echo "Die Summe von $1 und $2 ist: $summe"
}

# Teste die Funktion
addiere_zahlen 5 3        # Funktioniert: 5 + 3 = 8
addiere_zahlen 5 text     # Fehler: keine Zahl
addiere_zahlen 1          # Fehler: zu wenige Parameter

Wichtig für Anfänger:

  • Prüfe immer die Anzahl der Parameter
  • Prüfe den Inhalt der Parameter (z.B. ob es Zahlen sind)
  • Gib hilfreiche Fehlermeldungen aus
  • Verwende return 1 bei Fehlern
  • local vor Variablen macht sie nur in der Funktion verfügbar

Rückgabewerte von Funktionen

In Bash gibt es zwei Möglichkeiten, wie eine Funktion Werte zurückgeben kann.

Lass uns beide kennenlernen:
Mit dem return-Befehl (für Statuswerte):
Bash
#!/bin/bash

ist_gerade() {
    local zahl=$1
    
    # Prüfe, ob Parameter vorhanden
    if [ -z "$zahl" ]; then
        echo "Fehler: Keine Zahl angegeben"
        return 1
    fi
    
    # Prüfe, ob es eine Zahl ist
    if ! [[ $zahl =~ ^[0-9]+$ ]]; then
        echo "Fehler: Bitte eine positive Ganzzahl eingeben"
        return 1
    fi
    
    # Prüfe ob gerade
    if [ $((zahl % 2)) -eq 0 ]; then
        return 0    # 0 bedeutet "wahr" in Bash
    else
        return 1    # 1 bedeutet "falsch" in Bash
    fi
}

# Beispiel zur Verwendung
if ist_gerade 4; then
    echo "4 ist eine gerade Zahl"
else
    echo "4 ist eine ungerade Zahl"
fi
Mit echo (für Texte und Zahlen):
Bash
#!/bin/bash

multipliziere() {
    # Prüfe Parameter
    if [ $# -ne 2 ]; then
        echo "Fehler: Bitte zwei Zahlen eingeben"
        return 1
    fi
    
    local ergebnis=$(($1 * $2))
    echo $ergebnis
}

# Das Ergebnis in einer Variable speichern
resultat=$(multipliziere 5 3)
echo "5 mal 3 ist: $resultat"

Wichtig für Anfänger:

  • return kann nur Zahlen zwischen 0 und 255 zurückgeben
  • return 0 bedeutet „erfolgreich“ oder „wahr“
  • return 1 (oder höher) bedeutet „Fehler“ oder „falsch“
  • Für größere Zahlen oder Text verwende echo
  • Das Ergebnis einer Funktion kannst du mit $(...) in einer Variable speichern

Variablen in Funktionen

Wenn du Variablen in Funktionen verwendest, ist es wichtig zu verstehen, dass es zwei Arten gibt: lokale und globale Variablen.

Lass uns den Unterschied kennenlernen:
Lokale Variablen
Bash
#!/bin/bash

meine_funktion() {
    # Diese Variable ist nur in der Funktion sichtbar
    local mein_name="Max"
    echo "In der Funktion: $mein_name"
}

# Rufe die Funktion auf
meine_funktion
# Diese Ausgabe wird leer sein, weil die Variable lokal war
echo "Außerhalb der Funktion: $mein_name"
Globale Variablen
Bash
#!/bin/bash

# Das ist eine globale Variable
mein_alter=25

zeige_alter() {
    # Diese Funktion kann die globale Variable lesen
    echo "Das Alter ist: $mein_alter"
    
    # Sie kann die globale Variable auch ändern
    mein_alter=30
}

echo "Vor der Funktion: $mein_alter"
zeige_alter
echo "Nach der Funktion: $mein_alter"

Hier ein praktisches Beispiel, das beides kombiniert:

Bash
#!/bin/bash

# Globale Konfigurationsvariable
MAXIMAL_ALTER=120

pruefe_alter() {
    # Lokale Variable für den Parameter
    local alter=$1
    
    # Prüfe, ob eine Zahl eingegeben wurde
    if ! [[ $alter =~ ^[0-9]+$ ]]; then
        echo "Fehler: Bitte eine Zahl eingeben"
        return 1
    fi
    
    # Prüfe gegen globale Maximalgrenze
    if [ $alter -gt $MAXIMAL_ALTER ]; then
        echo "Fehler: Das Alter kann nicht größer als $MAXIMAL_ALTER sein"
        return 1
    fi
    
    echo "Das eingegebene Alter ($alter) ist gültig"
    return 0
}

# Teste die Funktion
pruefe_alter 25      # Gültig
pruefe_alter 150     # Zu hoch
pruefe_alter "abc"   # Keine Zahl

Wichtig für Anfänger:

  • Verwende local für Variablen, die nur in der Funktion gebraucht werden
  • Globale Variablen sind überall sichtbar
  • Globale Variablen können von Funktionen geändert werden
  • Verwende möglichst lokale Variablen, um Probleme zu vermeiden

Ein praktisches Beispiel

Lass uns alles bisher Gelernte in einem nützlichen Beispiel zusammenfassen. Wir erstellen einen einfachen Taschenrechner, der die vier Grundrechenarten beherrscht:

Bash
#!/bin/bash

# Funktion für die Addition
addiere() {
    local zahl1=$1
    local zahl2=$2
    echo $((zahl1 + zahl2))
}

# Funktion für die Subtraktion
subtrahiere() {
    local zahl1=$1
    local zahl2=$2
    echo $((zahl1 - zahl2))
}

# Funktion zur Prüfung der Eingaben
pruefe_zahlen() {
    # Prüfe, ob zwei Parameter übergeben wurden
    if [ $# -ne 2 ]; then
        echo "Fehler: Zwei Zahlen erforderlich"
        return 1
    fi
    
    # Prüfe, ob beide Parameter Zahlen sind
    if ! [[ $1 =~ ^[0-9]+$ ]] || ! [[ $2 =~ ^[0-9]+$ ]]; then
        echo "Fehler: Bitte nur positive Ganzzahlen eingeben"
        return 1
    fi
    
    return 0
}

# Hauptfunktion für die Berechnung
rechne() {
    local zahl1=$1
    local operator=$2
    local zahl2=$3
    
    # Prüfe die Eingaben
    if ! pruefe_zahlen $zahl1 $zahl2; then
        return 1
    fi
    
    # Führe die gewünschte Operation aus
    case $operator in
        "+")
            ergebnis=$(addiere $zahl1 $zahl2)
            ;;
        "-")
            ergebnis=$(subtrahiere $zahl1 $zahl2)
            ;;
        *)
            echo "Fehler: Unbekannter Operator. Bitte + oder - verwenden"
            return 1
            ;;
    esac
    
    echo "Das Ergebnis von $zahl1 $operator $zahl2 ist: $ergebnis"
}

# Beispielaufrufe
rechne 5 "+" 3
rechne 10 "-" 4
rechne 7 "x" 2    # Wird einen Fehler ausgeben
rechne abc "+" 3   # Wird einen Fehler ausgeben

Was haben wir hier gemacht?

  • Einzelne Funktionen für jede Rechenoperation
  • Eine Hilfsfunktion zur Überprüfung der Eingaben
  • Eine Hauptfunktion, die alles koordiniert
  • Fehlerprüfung an allen wichtigen Stellen
  • Sinnvolle Fehlermeldungen

Wichtige Konzepte, die wir verwendet haben:

  • Lokale Variablen in jeder Funktion
  • Parameterübergabe zwischen Funktionen
  • Rückgabewerte mit echo und return
  • Fehlerbehandlung
  • Verwendung von Kontrollstrukturen (case) in Funktionen

Übung

Um dein Verständnis für Funktionen zu vertiefen, hier eine praktische Übungsaufgabe.

Erweitere den Taschenrechner um folgende Funktionen:

  1. Füge die Multiplikation (*) und Division (/) hinzu
  2. Die Division soll prüfen, ob durch 0 geteilt wird
  3. Füge eine Funktion hinzu, die das letzte Ergebnis speichert
  4. Erstelle eine Funktion, die die Berechnungshistorie anzeigt

Anforderungen:

  • Verwende lokale Variablen wo sinnvoll
  • Prüfe alle Eingaben auf Gültigkeit
  • Gib hilfreiche Fehlermeldungen aus
  • Dokumentiere deine Funktionen mit Kommentaren

Hier ist eine mögliche Lösung:

Bash
#!/bin/bash

# Speichert das letzte Ergebnis
letztes_ergebnis=0
# Array für die Historie
declare -a historie

# Funktion für die Multiplikation
multipliziere() {
    local zahl1=$1
    local zahl2=$2
    echo $((zahl1 * zahl2))
}

# Funktion für die Division
dividiere() {
    local zahl1=$1
    local zahl2=$2
    
    # Prüfe Division durch 0
    if [ $zahl2 -eq 0 ]; then
        echo "Fehler: Division durch 0 nicht möglich"
        return 1
    fi
    
    echo $((zahl1 / zahl2))
}

# Funktion zum Speichern in der Historie
speichere_berechnung() {
    local berechnung="$1 $2 $3 = $4"
    historie+=("$berechnung")
}

# Funktion zum Anzeigen der Historie
zeige_historie() {
    echo "=== Berechnungshistorie ==="
    if [ ${#historie[@]} -eq 0 ]; then
        echo "Noch keine Berechnungen durchgeführt"
    else
        for eintrag in "${historie[@]}"; do
            echo "$eintrag"
        done
    fi
    echo "=========================="
}

Fazit

In diesem vierten Teil unseres Bash-Grundkurses hast du gelernt, wie du Funktionen erstellst und einsetzt. Funktionen sind ein wichtiges Werkzeug, um deinen Code zu strukturieren und wiederzuverwenden. Du kannst jetzt Parameter übergeben, Rückgabewerte verarbeiten und lokale Variablen verwenden. Das praktische Beispiel des Taschenrechners hat gezeigt, wie verschiedene Funktionen zusammenarbeiten können, um eine komplexere Aufgabe zu lösen.

Im nächsten Teil unserer Serie werden wir uns mit Ein- und Ausgabe in Bash beschäftigen. Du wirst lernen, wie du Daten von der Tastatur einliest, in Dateien schreibst und zwischen Programmen austauschst.

Bis dahin, happy scripting!

Kommentar verfassen