Einführung
Linux-Befehle lesen ihre Eingaben normalerweise aus dem Terminal und schreiben ihre Ergebnisse ebenfalls dorthin. Die Shell kann diese Datenströme stattdessen mit Dateien oder anderen Befehlen verbinden. Dies wird als Umleitung bezeichnet und bildet die Grundlage für Protokollierung, Pipelines, Hintergrundaufgaben und Shell-Skripte.
In diesem Lab arbeiten Sie mit Standardeingabe, Standardausgabe und Standardfehler. Sie lernen, wann > vorhandene Inhalte überschreibt und wann >> Inhalte anhängt, wie 2> und 2>&1 Fehler behandeln, wie eine Pipe Daten weitergibt, wie tee dieselbe Ausgabe anzeigt und speichert und wann /dev/null nützlich ist.
Standardeingabe, Standardausgabe und Standardfehler verstehen
In diesem Schritt erstellen Sie eine kleine Eingabedatei und verbinden sie über die Standardeingabe mit Befehlen.
Jeder Befehl beginnt mit drei Standarddatenströmen:
| Deskriptor | Bezeichnung | Standardverbindung |
|---|---|---|
0 |
Standardeingabe oder stdin | Tastatur |
1 |
Standardausgabe oder stdout | Terminal |
2 |
Standardfehler oder stderr | Terminal |
Erstellen Sie ein Arbeitsverzeichnis und wechseln Sie hinein:
mkdir -p /home/labex/project/streams-lab
cd /home/labex/project/streams-lab
Erstellen Sie mit einem Here-Dokument eine Eingabedatei mit drei Zeilen. Die Shell übergibt die Zeilen zwischen den beiden EOF-Markierungen an cat. Der Operator > speichert die Ausgabe von cat in input.txt:
cat > input.txt <<'EOF'
alpha
beta
gamma
EOF
Normalerweise erhält cat input.txt einen Dateinamen als Argument. Der Operator < verbindet die Datei stattdessen mit Deskriptor 0, also mit der Standardeingabe:
cat < input.txt
Sie sollten die drei Zeilen sehen. Verwenden Sie dieselbe Eingabeumleitung mit wc -l, das die Zeilen zählt:
wc -l < input.txt
Die Ausgabe sollte 3 sein. Da der Dateiname kein Argument für wc ist, wird nur die Zahl ausgegeben.
Standardausgabe umleiten und anhängen
In diesem Schritt leiten Sie die normale Ausgabe eines Befehls um und beobachten den Unterschied zwischen Überschreiben und Anhängen.
Stellen Sie sicher, dass Sie sich im Arbeitsverzeichnis für Datenströme befinden:
cd /home/labex/project/streams-lab
Der Operator > verbindet Deskriptor 1, also die Standardausgabe, mit einer Datei. Er erstellt die Datei oder leert ihren vorhandenen Inhalt, bevor er schreibt:
echo "Stream report" > report.txt
cat report.txt
Führen Sie eine weitere Überschreibung aus. Dadurch verschwindet die vorherige Zeile:
echo "Input lines: 3" > report.txt
cat report.txt
Verwenden Sie nun >>. Dieser Operator öffnet das Ziel im Anhängemodus:
echo "Status: complete" >> report.txt
cat report.txt
Die Datei sollte genau zwei Zeilen enthalten: Input lines: 3, gefolgt von Status: complete. Die Shell führt die Umleitung aus, bevor der Befehl startet.
Standardausgabe und Standardfehler trennen
In diesem Schritt führen Sie einen Befehl aus, der sowohl eine normale Ausgabe als auch einen Fehler erzeugt. Anschließend speichern Sie jeden Datenstrom in einer eigenen Datei.
Der folgende ls-Befehl erhält einen vorhandenen und einen nicht vorhandenen Pfad:
cd /home/labex/project/streams-lab
ls -l input.txt missing.txt
Die Zeile zu input.txt wird über stdout ausgegeben. Die Meldung No such file or directory wird über stderr ausgegeben. Standardmäßig erscheinen beide Datenströme im Terminal, sie bleiben jedoch getrennt.
Leiten Sie Deskriptor 1 mit > und Deskriptor 2 mit 2> um:
ls -l input.txt missing.txt > listing.log 2> errors.log
Der Befehl liefert weiterhin einen Status ungleich null zurück, weil ein Pfad fehlt. Die Shell bleibt jedoch für den nächsten Befehl bereit. Prüfen Sie die Zieldateien:
cat listing.log
cat errors.log
listing.log sollte input.txt erwähnen, aber keinen Fehler enthalten. errors.log sollte missing.txt und die Fehlermeldung enthalten, jedoch nicht die erfolgreiche Dateiliste.
Standardausgabe und Standardfehler zusammenführen
In diesem Schritt leiten Sie stdout und stderr in ein gemeinsames Protokoll um und lernen, warum die Reihenfolge der Umleitungen wichtig ist.
Leiten Sie zunächst stdout nach combined.log um. Verweisen Sie anschließend mit Deskriptor 2 auf das aktuelle Ziel von Deskriptor 1:
cd /home/labex/project/streams-lab
ls -l input.txt missing.txt > combined.log 2>&1
Der Ausdruck 2>&1 bedeutet: „Leite Deskriptor 2 an dasselbe Ziel weiter, das Deskriptor 1 derzeit verwendet.“ Da > combined.log zuerst erscheint, gelangen beide Datenströme in die Datei.
cat combined.log
Die Datei sollte sowohl die Auflistung von input.txt als auch den Fehler zu missing.txt enthalten.
Bash unterstützt außerdem &> als Kurzform, um beide Datenströme umzuleiten:
ls -l report.txt absent.txt &> shorthand.log
cat shorthand.log
Diese zweite Datei sollte die erfolgreiche Auflistung von report.txt sowie den Fehler zu absent.txt enthalten. Die portable Form > file 2>&1 wird besonders häufig in Skripten und Dienstbefehlen verwendet.
Pipeline-Ausgabe mit Tee anzeigen und speichern
In diesem Schritt verwenden Sie eine Pipeline und tee, um die Ausgabe anzuzeigen und dieselben Daten gleichzeitig in einer Datei zu speichern.
Eine Pipe, geschrieben als |, verbindet stdout des Befehls auf der linken Seite mit stdin des Befehls auf der rechten Seite. Sortieren Sie die Eingabedatei in umgekehrter alphabetischer Reihenfolge:
cd /home/labex/project/streams-lab
sort -r input.txt
Bei einer gewöhnlichen Ausgabeumleitung werden die sortierten Zeilen in eine Datei geschrieben und erscheinen nicht mehr im Terminal:
sort -r input.txt > sorted.txt
cat sorted.txt
Der Befehl tee kopiert seine stdin sowohl nach stdout als auch in eine angegebene Datei. Führen Sie dieselbe Sortierung über eine Pipe aus:
sort -r input.txt | tee sorted.txt
Sie sollten die sortierten Zeilen auf dem Bildschirm sehen. Gleichzeitig erhält sorted.txt denselben Inhalt. Standardmäßig überschreibt tee sein Ziel genauso wie >.
Mit der Option -a hängt tee Daten an. Fügen Sie eine weitere Zeile hinzu und zeigen Sie sie dabei an:
echo "delta" | tee -a sorted.txt
cat sorted.txt
Die Datei sollte nun gamma, beta, alpha und delta enthalten. tee ist nützlich, wenn Sie gleichzeitig eine direkte Rückmeldung im Terminal und ein gespeichertes Protokoll benötigen.
Nicht benötigte Daten mit Dev Null verwerfen
In diesem Schritt verwerfen Sie absichtlich einen Datenstrom mit /dev/null, bewahren nützliche Ausgaben mit tee auf und leeren ein vorhandenes Protokoll.
/dev/null ist ein spezielles Gerät, das alles annimmt und verwirft, was dorthin geschrieben wird. Listen Sie ein vorhandenes und ein nicht vorhandenes Verzeichnis auf und verwerfen Sie dabei nur stderr:
cd /home/labex/project/streams-lab
ls -l . missing-directory 2> /dev/null
Sie sollten die Verzeichnisliste sehen, aber keine Fehlermeldung zu missing-directory. Kombinieren Sie dies mit tee, damit die sichtbare stdout-Ausgabe zusätzlich gespeichert wird:
ls -l . missing-directory 2> /dev/null | tee visible-listing.log
Die Pipe überträgt nur stdout. stderr wurde separat nach /dev/null umgeleitet, bevor die Pipe Daten erhalten hat.
Prüfen Sie die gespeicherte Liste:
cat visible-listing.log
Erstellen Sie abschließend ein temporäres Arbeitsprotokoll. Verwenden Sie danach /dev/null als leere Eingabequelle, um seinen Inhalt zu löschen. Eine separate Datei bewahrt die Informationen über die zusammengeführten Datenströme aus Schritt 4 auf:
echo "outdated scratch data" > scratch.log
cat /dev/null > scratch.log
Prüfen Sie die Dateigröße:
ls -l scratch.log
Die Datei sollte weiterhin vorhanden sein und eine Größe von 0 Byte haben. Verwenden Sie das Verwerfen von Daten bewusst: Ausgeblendete Fehler können die Fehlersuche erschweren, wenn Sie die Diagnoseinformationen tatsächlich benötigen.
Zusammenfassung
Sie haben die drei Standarddatenströme und ihre Dateideskriptoren geübt, Dateien mit < an stdin angeschlossen und stdout mit > und >> umgeleitet. Sie haben stderr mit 2> getrennt, mit 2>&1 und &> mit stdout zusammengeführt und gelernt, warum die Reihenfolge der Operatoren wichtig ist.
Außerdem haben Sie die gewöhnliche Dateiumleitung mit Pipelines und tee verglichen, mit tee -a Daten während der Anzeige angehängt und nicht benötigte Daten mit /dev/null verworfen. Diese Muster helfen Ihnen später im Kurs beim Verständnis von Protokollierung, Hintergrundbefehlen und Shell-Skripten.



