12.4Ein- und Ausgabeumleitung

Bei der Ausführung von Kommandos in der bash existieren drei sogenannte Standarddateien. Der Begriff »Datei« stiftet dabei ein wenig Verwirrung: Es handelt sich eigentlich nicht um richtige Dateien, sondern um Dateideskriptoren, die auf Betriebssystemebene wie Dateien behandelt werden.

An sich ist das alles selbstverständlich – woher sonst als von der Tastatur sollten die Eingaben kommen, wo sonst als auf dem Bildschirm sollten Ergebnisse oder Fehler angezeigt werden? Bemerkenswert ist aber die Möglichkeit, die Standardeingabe oder -ausgabe umzuleiten.

Beispielsweise kann der Fall auftreten, dass das Inhaltsverzeichnis des aktuellen Verzeichnisses nicht auf dem Bildschirm angezeigt, sondern in einer Datei gespeichert werden soll. Die Standardausgabe soll also in eine echte Datei umgeleitet werden. Das erfolgt in der bash durch das Zeichen >:

user$ ls *.tex > inhalt

In der Textdatei inhalt befindet sich jetzt eine Liste aller *.tex-Dateien im aktuellen Verzeichnis. Diese Form der Ausgabeumleitung ist sicherlich die häufigste Anwendung. Daneben existieren aber viele weitere Varianten: 2> datei leitet alle Fehlermeldungen in die angegebene Datei. >& datei bzw. &> datei leiten sowohl die Standardausgabe als auch alle Fehlermeldungen in die angegebene Datei. Wenn statt > die Verdoppelung >> verwendet wird, dann werden die jeweiligen Ausgaben an das Ende einer bereits bestehenden Datei angehängt. Diese und weitere Codes zur Ein- und Ausgabeumleitung sind in Tabelle 12.2 zusammengefasst.

Kommando

Funktion

kommando > datei

leitet Standardausgaben zur angegebenen Datei.

kommando < datei

liest Eingaben aus der angegebenen Datei.

kommando 2> datei

leitet Fehlermeldungen zur angegebenen Datei.

kommando >& datei

leitet Ausgaben und Fehler um.

kommando &> datei

leitet ebenfalls Ausgaben und Fehler um.

kommando >> datei

hängt Standardausgaben an die vorhandene Datei an.

kommando &>> datei

hängt Ausgaben und Fehler an die Datei an (ab bash 4.0).

kommando1 | kommando2

leitet Ausgaben von Kommando 1 an Kommando 2 weiter.

komm | tee datei

zeigt die Ausgaben an und speichert zugleich eine Kopie.

Tabelle 12.2Ein- und Ausgabeumleitung

Eine Eingabeumleitung erfolgt mit < datei: Kommandos, die Eingaben von der Tastatur erwarten, lesen diese damit aus der angegebenen Datei.

Vorsicht

Es ist nicht möglich, eine Datei zu bearbeiten und gleichzeitig das Ergebnis wieder in diese Datei zu schreiben! sort dat > dat oder auch sort < dat > dat führt dazu, dass dat gelöscht wird!

Pipes werden mit dem Zeichen | gebildet. Dabei wird die Ausgabe des ersten Kommandos als Eingabe für das zweite Kommando verwendet. In der Praxis werden Sie Pipes oft zusammen mit dem Kommando less bilden, wenn Sie längere Ausgaben seitenweise betrachten möchten.

user$ ls -l | less

Durch das obige Kommando wird das Inhaltsverzeichnis des aktuellen Verzeichnisses ermittelt und in eine Pipe geschrieben. Von dort liest das parallel ausgeführte Kommando less seine Eingaben und zeigt sie auf dem Bildschirm an.

Pipes eignen sich auch hervorragend dazu, unterschiedliche Kommandos zu kombinieren. So liefert das folgende Kommando eine sortierte Liste aller installierten RPM-Pakete:

user$ rpm -qa | sort

Statt Pipes können zur Ein- und Ausgabeumleitung auch sogenannte FIFO-Dateien verwendet werden. FIFO steht für First In First Out und realisiert die Idee einer Pipe in Form einer Datei. FIFOs sind bei der Eingabe viel umständlicher als Pipes, sie machen aber deutlich, was das Zeichen | eigentlich bewirkt. In der Praxis werden sie verwendet, damit zwei voneinander unabhängige Programme miteinander kommunizieren können.

user$ mkfifo fifo user$ ls -l > fifo & user$ less < fifo

Durch die drei obigen Kommandos wird zuerst eine FIFO-Datei eingerichtet. Anschließend wird ls als Hintergrundprozess gestartet. Er schreibt seine Ausgaben in die Datei. Von dort liest less die Daten wieder aus und zeigt sie auf dem Bildschirm an.

Zur Formulierung einer Pipe eignen sich nur solche Kommandos, die die zu verarbeitenden Kommandos aus dem Standardeingabekanal lesen. Wenn das nicht der Fall ist, können Sie ähnliche Effekte durch eine Kommandosubstitution oder durch das Kommando xargs erzielen. Diese und andere Substitutionsmechanismen sind Thema von Abschnitt 12.6.

Ausgabevervielfachung mit »tee«

Gelegentlich kommt es vor, dass die Ausgaben eines Programms zwar in einer Datei gespeichert werden sollen, dass Sie aber dennoch parallel am Bildschirm den Programmverlauf verfolgen wollen. In diesem Fall ist eine Verdoppelung der Ausgabe erforderlich, wobei eine Kopie auf dem Bildschirm angezeigt und die zweite Kopie in einer Datei gespeichert wird. Diese Aufgabe übernimmt das Kommando tee:

user$ ls | tee inhalt

Das Inhaltsverzeichnis des aktuellen Verzeichnisses wird auf dem Bildschirm angezeigt und gleichzeitig in der Datei inhalt gespeichert. Dabei erfolgt zuerst eine Weiterleitung der Standardausgabe an das Kommando tee. Dieses Kommando zeigt standardmäßig die Standardausgabe auf dem Terminal an und speichert die Kopie davon in der angegebenen Datei. Dass es sich wirklich um eine Vervielfachung der Ausgabe handelt, bemerken Sie, wenn Sie auch die Standardausgabe von tee in eine Datei weiterleiten:

user$ ls | tee inhalt1 > inhalt2

Das Ergebnis sind zwei identische Dateien, inhalt1 und inhalt2. Das obige Kommando hat reinen Beispielcharakter. Etwas schwieriger zu verstehen, dafür aber sinnvoller, ist das folgende Beispiel:

user$ ls -l | tee inhalt1 | sort +4 > inhalt2

In inhalt1 befindet sich wiederum das »normale« Inhaltsverzeichnis, das von ls automatisch nach Dateinamen sortiert wurde. Die Kopie dieser Ausgabe wurde an sort weitergegeben, dort nach der Dateigröße (fünfte Spalte, also Option +4) sortiert und in inhalt2 gespeichert.