Bash: Kommando-Ausgaben in eine Datei umleiten (Logging)
March 7, 2019
In der Shell-Programmierung ist es oft notwendig, die Ausgabe von Befehlen zur späteren Analyse oder zur Fehlerbehebung in eine Datei zu schreiben. Jedes Kommandozeilen-Programm hat zwei primäre Ausgabeströme:
- Standardausgabe (stdout, File Descriptor 1): Für normale Programmausgaben.
- Standardfehlerausgabe (stderr, File Descriptor 2): Für Fehlermeldungen und Diagnosen.
Diese Anleitung zeigt verschiedene Methoden, um diese Ausgabeströme in Dateien umzuleiten.
1. Grundlegende Umleitungsoperatoren
Standardausgabe (stdout) umleiten
>(Überschreiben): Leitetstdoutin eine Datei um und überschreibt deren Inhalt, falls die Datei bereits existiert.codels -l > file.log>>(Anhängen): Leitetstdoutin eine Datei um und hängt die Ausgabe am Ende an.codeecho "Skript gestartet: $(date)" >> application.log
Standardfehlerausgabe (stderr) umleiten
Um stderr umzuleiten, muss explizit der File Descriptor 2 angegeben werden.
# Leitet nur Fehlermeldungen in die Datei um
grep "fehler" non_existent_file 2> error.log
2. stdout und stderr kombinieren
In getrennte Dateien umleiten
# stdout geht nach out.log, stderr nach err.log
./mein_skript.sh > out.log 2> err.log
In dieselbe Datei umleiten (Bash 4+)
Der &>-Operator ist eine Kurzform, um sowohl stdout als auch stderr in dieselbe Datei umzuleiten.
# Überschreibt die Datei mit beiden Ausgabeströmen
./mein_skript.sh &> all.log
# Hängt beide Ausgabeströme an
./mein_skript.sh &>> all.log
In dieselbe Datei umleiten (POSIX-konform)
Diese Methode ist portabler und funktioniert auch in älteren Shells.
# Leitet stdout nach all.log und dann stderr dorthin, wo stdout hinzeigt
./mein_skript.sh > all.log 2>&1
Wichtig: Die Reihenfolge 2>&1 ist entscheidend. Würde man 2>&1 > all.log schreiben, würde stderr an den ursprünglichen Ort von stdout (das Terminal) umgeleitet, bevor stdout in die Datei umgeleitet wird.
3. Ausgabe gleichzeitig anzeigen und speichern (tee)
Der tee-Befehl liest von der Standardeingabe und schreibt den Inhalt sowohl in eine Datei als auch auf die Standardausgabe (das Terminal).
# Zeigt die Ausgabe von 'ls -l' an UND speichert sie in output.txt
ls -l | tee output.txt
# Hängt die Ausgabe an die Datei an (-a für append)
ls -l | tee -a output.txt
4. Ausgabe eines gesamten Skripts loggen
Um die gesamte Ausgabe eines Skripts (alle Befehle) in eine Datei zu loggen, können Sie den exec-Befehl am Anfang des Skripts verwenden.
#!/usr/bin/env bash
LOG_FILE="script_run.log"
# Leitet alle nachfolgenden stdout- und stderr-Ausgaben in die Log-Datei um
# und zeigt sie gleichzeitig über 'tee' im Terminal an.
exec &> >(tee -a "$LOG_FILE")
echo "Diese Zeile wird im Terminal angezeigt und in die Log-Datei geschrieben."
echo "Das gilt auch für Fehlermeldungen." >&2
Fazit
Die Kontrolle über stdout und stderr ist fundamental für das Schreiben robuster und gut diagnostizierbarer Bash-Skripte. Während die grundlegenden Umleitungsoperatoren (>, >>, 2>) für die meisten Anwendungsfälle ausreichen, bieten tee und exec erweiterte Möglichkeiten für interaktives Logging und die Protokollierung ganzer Skript-Abläufe.