Bash Grundkurs #5: Ein- und Ausgabe in Bash

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

In den vorherigen Artikeln hast du gelernt, wie du Skripte erstellst, mit Variablen arbeitest, Kontrollstrukturen verwendest und Funktionen schreibst. Heute lernst du, wie deine Skripte mit der Außenwelt kommunizieren können – durch Ein- und Ausgabe.

Wie wichtig ist die Ein- und Ausgabe?

Ein Skript, das nicht mit seiner Umgebung kommunizieren kann, ist wie ein Mensch ohne Sinne. Es braucht Möglichkeiten, Informationen aufzunehmen (Eingabe) und Ergebnisse mitzuteilen (Ausgabe).

In Bash gibt es verschiedene Wege, dies zu tun:

  • Eingaben von der Tastatur lesen
  • Text auf dem Bildschirm ausgeben
  • Daten in Dateien speichern
  • Informationen aus Dateien lesen

Lass uns mit der einfachsten Form der Ausgabe beginnen – dem Anzeigen von Text auf dem Bildschirm.

Text ausgeben mit echo

Der echo-Befehl ist dein wichtigstes Werkzeug für die Ausgabe.

Du hast ihn bereits in den vorherigen Artikeln kennengelernt:

Bash
#!/bin/bash

# Einfache Textausgabe
echo "Hallo, willkommen zu Ein- und Ausgabe in Bash!"

# Variablen ausgeben
name="Max"
echo "Hallo $name"

# Mehrere Zeilen ausgeben
echo "Erste Zeile"
echo "Zweite Zeile"

Erweiterte Ausgabemöglichkeiten

Der echo-Befehl mit Formatierung

Der echo-Befehl kann mehr als nur einfachen Text ausgeben.

Mit der Option -e kannst du spezielle Formatierungen verwenden:

Bash
#!/bin/bash

# Neue Zeile mit \n
echo -e "Erste Zeile\nZweite Zeile"

# Tabulator mit \t
echo -e "Name:\tMax\nAlter:\t25"

# Text hervorheben
echo -e "\033[1mFett\033[0m"
echo -e "\033[31mRot\033[0m"
echo -e "\033[44mBlauer Hintergrund\033[0m"
Formatierte Ausgabe mit printf

Für noch mehr Kontrolle über das Ausgabeformat gibt es den printf-Befehl:

Bash
#!/bin/bash

# Grundlegende printf-Syntax
printf "Hallo, %s!\n" "Max"

# Zahlen formatieren
printf "Nummer: %d\n" 42
printf "Preis: %.2f €\n" 9.99

# Tabelle erstellen
printf "%-10s %5s %8s\n" "Name" "Alter" "Stadt"
printf "%-10s %5d %8s\n" "Max" 25 "Berlin"
printf "%-10s %5d %8s\n" "Anna" 30 "Hamburg"

Wichtig für Anfänger:

  • %s ist ein Platzhalter für Text (Strings)
  • %d ist für ganze Zahlen
  • %f ist für Dezimalzahlen
  • \n erzeugt eine neue Zeile
  • Die Zahl nach % bestimmt die Feldbreite
  • - links-bündig statt rechts-bündig
  • .2 bei %.2f gibt die Anzahl der Dezimalstellen an

Benutzereingaben einlesen

Der read-Befehl ist dein Werkzeug, um Eingaben von der Tastatur zu lesen.

Lass uns verschiedene Möglichkeiten kennenlernen:

Einfache Eingabe
Bash
#!/bin/bash

# Grundlegende Verwendung von read
echo "Wie heißt du?"
read name
echo "Hallo $name!"

# Mit eigener Eingabeaufforderung
read -p "Wie alt bist du? " alter
echo "Du bist also $alter Jahre alt."
Sichere Eingabe mit Überprüfung
Bash
#!/bin/bash

# Eingabe mit Überprüfung
while true; do
    read -p "Gib eine Zahl zwischen 1 und 10 ein: " zahl
    
    # Prüfe, ob die Eingabe eine Zahl ist
    if ! [[ $zahl =~ ^[0-9]+$ ]]; then
        echo "Fehler: Bitte nur Zahlen eingeben!"
        continue
    fi
    
    # Prüfe den Wertebereich
    if [ $zahl -lt 1 ] || [ $zahl -gt 10 ]; then
        echo "Fehler: Die Zahl muss zwischen 1 und 10 liegen!"
        continue
    fi
    
    echo "Danke! Du hast $zahl eingegeben."
    break
done
Verschiedene read-Optionen
Bash
#!/bin/bash

# Zeitlimit für die Eingabe
read -t 5 -p "Du hast 5 Sekunden Zeit zu antworten: " antwort
if [ -z "$antwort" ]; then
    echo -e "\nZeit abgelaufen!"
fi

# Passwort eingeben (ohne Anzeige)
read -s -p "Passwort eingeben: " passwort
echo -e "\nDanke für die Eingabe!"

# Mehrere Werte einlesen
read -p "Gib drei Zahlen ein (durch Leerzeichen getrennt): " zahl1 zahl2 zahl3
echo "Du hast eingegeben: $zahl1, $zahl2 und $zahl3"

Wichtige read-Optionen:

  • -p zeigt eine Eingabeaufforderung
  • -s versteckt die Eingabe (für Passwörter)
  • -t setzt ein Zeitlimit in Sekunden
  • -n begrenzt die Anzahl der einzulesenden Zeichen
  • -r verhindert, dass Backslash als Escape-Zeichen interpretiert wird

Arbeiten mit Dateien

In Bash gibt es verschiedene Möglichkeiten, mit Dateien zu arbeiten.

Lass uns die wichtigsten Methoden kennenlernen:

Aus Dateien lesen
Bash
#!/bin/bash

# Eine Datei zeilenweise lesen
echo "Inhalt der Datei zeilenweise lesen:"
while IFS= read -r zeile; do
    echo "$zeile"
done < "beispiel.txt"

# Kompletten Inhalt auf einmal lesen
inhalt=$(<beispiel.txt)
echo -e "\nKompletter Inhalt:"
echo "$inhalt"

# Bestimmte Zeilen lesen
echo -e "\nNur die erste Zeile:"
head -n 1 beispiel.txt

echo -e "\nNur die letzte Zeile:"
tail -n 1 beispiel.txt
In Dateien schreiben
Bash
#!/bin/bash

# Neue Datei erstellen oder überschreiben
echo "Das ist die erste Zeile" > neue_datei.txt
echo "Das ist die zweite Zeile" >> neue_datei.txt

# Mehrere Zeilen auf einmal schreiben
cat > mehrere_zeilen.txt << EOF
Zeile 1: Hallo
Zeile 2: Das ist ein Test
Zeile 3: Bash ist toll
EOF

# Inhalt anzeigen
echo "Inhalt der neuen Datei:"
cat neue_datei.txt

echo -e "\nInhalt der mehrere_zeilen.txt:"
cat mehrere_zeilen.txt

Wichtige Operatoren:

  • > überschreibt eine Datei
  • >> hängt an eine Datei an
  • < liest aus einer Datei
  • <<EOF ermöglicht Mehrzeilen-Eingabe (Here-Document)
Dateien überprüfen
Bash
#!/bin/bash

dateiname="test.txt"

# Prüfe, ob Datei existiert
if [ -f "$dateiname" ]; then
    echo "Die Datei existiert"
    
    # Prüfe Lese- und Schreibrechte
    if [ -r "$dateiname" ]; then
        echo "Die Datei ist lesbar"
    fi
    
    if [ -w "$dateiname" ]; then
        echo "Die Datei ist beschreibbar"
    fi
else
    echo "Die Datei existiert nicht"
fi

Wichtige Dateitests:

  • -f prüft, ob eine reguläre Datei existiert
  • -d prüft, ob ein Verzeichnis existiert
  • -r prüft Leserechte
  • -w prüft Schreibrechte
  • -x prüft Ausführungsrechte
  • -s prüft, ob die Datei nicht leer ist

Ein- und Ausgabe umleiten

In Bash kannst du die Standardeingabe, -ausgabe und Fehlerausgabe umleiten. Das ist besonders nützlich für die Automatisierung und Protokollierung.

Grundlegende Umleitungen
Bash
#!/bin/bash

# Ausgabe in Datei umleiten
echo "Das geht in eine Datei" > ausgabe.txt

# Fehlerausgabe umleiten
ls nicht_existierende_datei 2> fehler.txt

# Beide Ausgaben in verschiedene Dateien umleiten
ls existiert_nicht alle_dateien 1> normal.txt 2> fehler.txt

# Beide Ausgaben in dieselbe Datei umleiten
ls -la &> alle_ausgaben.txt

Wichtige Umleitungsoperatoren:

  • 1> oder > – Standardausgabe umleiten
  • 2> – Fehlerausgabe umleiten
  • &> – beide Ausgaben umleiten
  • >> – an Datei anhängen statt überschreiben
  • < – Eingabe aus Datei lesen
Pipes verwenden

Mit Pipes (|) kannst du die Ausgabe eines Befehls als Eingabe für einen anderen Befehl verwenden:

Bash
#!/bin/bash

# Zähle Zeilen in einer Datei
cat beispiel.txt | wc -l

# Finde bestimmte Wörter und zähle sie
echo "Apfel Banane Apfel Orange Apfel" | grep -o "Apfel" | wc -l

# Sortiere und zeige nur eindeutige Einträge
echo -e "Zeile 1\nZeile 2\nZeile 1" | sort | uniq
Praktisches Beispiel
Logfile-Verarbeitung
Bash
#!/bin/bash

# Funktion zum Protokollieren
protokolliere() {
    local nachricht="$1"
    local zeitstempel=$(date "+%Y-%m-%d %H:%M:%S")
    
    # Protokolliere in Datei und zeige auf Bildschirm
    echo "[$zeitstempel] $nachricht" | tee -a protokoll.txt
}

# Beispielverwendung
protokolliere "Skript gestartet"

# Fehler protokollieren
if ! ls nicht_existierend 2>/dev/null; then
    protokolliere "Fehler: Datei nicht gefunden"
fi

protokolliere "Skript beendet"

# Zeige das Protokoll
echo -e "\nInhalt des Protokolls:"
cat protokoll.txt

Wichtige Befehle für die Verarbeitung:

  • grep – Suchen nach Text
  • sort – Sortieren von Zeilen
  • uniq – Doppelte Zeilen entfernen
  • wc – Zeilen/Wörter/Zeichen zählen
  • tee – Ausgabe in Datei und auf Bildschirm

Übung

Erstelle ein Adressbuch-Skript, das folgende Anforderungen erfüllt:

  1. Das Skript soll:
    • Kontakte hinzufügen können
    • Kontakte anzeigen können
    • Nach Kontakten suchen können
    • Alle Daten in einer Datei speichern
  2. Für jeden Kontakt sollen:
    • Name
    • Telefonnummer
    • E-Mail-Adresse
      gespeichert werden
  3. Beachte:
    • Überprüfe alle Eingaben auf Gültigkeit
    • Speichere die Daten strukturiert
    • Behandle mögliche Fehler

Hier ist eine mögliche Lösung:

Bash
#!/bin/bash

# Konfiguration
ADRESSBUCH="adressbuch.txt"

# Kontakt hinzufügen
kontakt_hinzufuegen() {
    # Eingaben sammeln
    read -p "Name: " name
    read -p "Telefon: " telefon
    read -p "E-Mail: " email
    
    # Eingaben überprüfen
    if [ -z "$name" ] || [ -z "$telefon" ] || [ -z "$email" ]; then
        echo "Fehler: Alle Felder müssen ausgefüllt werden"
        return 1
    fi
    
    # E-Mail-Format prüfen (einfache Prüfung)
    if ! [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
        echo "Fehler: Ungültige E-Mail-Adresse"
        return 1
    fi
    
    # In Datei speichern
    echo "$name;$telefon;$email" >> "$ADRESSBUCH"
    echo "Kontakt wurde gespeichert"
}

# Kontakte anzeigen
kontakte_anzeigen() {
    if [ ! -f "$ADRESSBUCH" ]; then
        echo "Keine Kontakte vorhanden"
        return
    fi
    
    echo "=== Adressbuch ==="
    while IFS=';' read -r name telefon email; do
        echo "Name: $name"
        echo "Telefon: $telefon"
        echo "E-Mail: $email"
        echo "----------------"
    done < "$ADRESSBUCH"
}

# Nach Kontakten suchen
kontakt_suchen() {
    read -p "Suchbegriff eingeben: " suche
    
    if [ ! -f "$ADRESSBUCH" ]; then
        echo "Keine Kontakte vorhanden"
        return
    fi
    
    echo "=== Suchergebnisse ==="
    grep -i "$suche" "$ADRESSBUCH" | while IFS=';' read -r name telefon email; do
        echo "Name: $name"
        echo "Telefon: $telefon"
        echo "E-Mail: $email"
        echo "----------------"
    done
}

Fazit

In diesem fünften Teil unseres Bash-Grundkurses hast du gelernt, wie deine Skripte mit der Außenwelt kommunizieren können. Du kennst jetzt die verschiedenen Möglichkeiten der Ein- und Ausgabe in Bash, von einfachen Bildschirmausgaben bis hin zur Dateiverarbeitung. Du weißt, wie du Benutzereingaben einliest, diese überprüfst und wie du Daten dauerhaft in Dateien speicherst.

Die Fähigkeit, Ein- und Ausgabe zu verarbeiten, ist fundamental für jedes Bash-Skript. Mit diesem Wissen kannst du nun interaktive Skripte schreiben, Daten verarbeiten und Ergebnisse speichern.

Im nächsten Teil unserer Serie werden wir uns mit der Fehlerbehandlung und dem Debugging in Bash beschäftigen. Du wirst lernen, wie du deine Skripte robuster machst und Probleme effektiv findest und behebst.

Bis dahin, happy scripting!

Kommentar verfassen