1.103.4 Unix Streams, Pipes und Umleitungen

(Last Updated On: 3. Oktober 2013)
lupus

Quelle für 1.103 Bild

Zurück zu 1.103 GNU und Unix Kommandos bzw. Linux Zertifizierungen LPIC-1 [101]: Unterlagen.
Prüfungskandidaten sollten in der Lage sein, Ein- und Ausgabeströme umzuleiten und sie zu verknüpfen, um Textdaten effizient zu verarbeiten. Dieses Lernziel beinhaltet das Umleiten von Standardeingabe, Standardausgabe und Standardfehlerausgabe, das Umleiten der Ausgabe eines Kommandos in die Eingabe eines anderen Kommandos, das Verwenden der Ausgabe eines Kommandos als Argument für ein anderes Kommando und das gleichzeitige Senden einer Ausgabe sowohl an die Standardausgabe als auch in eine Datei.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

tee, xargs, <, <<, >, >>, |, ‘‘
Siehe auch man tee und man xargs und zu den Standard-Datenströme siehe auch auf Wikipedia stdout.
Grundlegendes Prinzip
Jedes Programm unter Linux besitzt drei Standardkanäle für die Datenein und -ausgabe. Diese drei Kanäle sind
Standard-Eingabe (STDIN)
Der Kanal, von dem das Programm seine Eingabe erwartet. Dieser Kanal besitzt die Kenn-Nummer 0 und ist normalerweise mit der Tastatur verbunden.
Standard-Ausgabe (STDOUT)
Der Kanal, auf den das Programm seine Ausgaben schreibt. Dieser Kanal besitzt die Kenn-Nummer 1 und ist normalerweise mit dem Monitor verbunden.
Standard-Fehlerausgabe (STDERR)
Der Kanal, auf den das Programm seine Fehlerausgaben schreibt. Dieser Kanal besitzt die Kenn-Nummer 2 und ist wie STDOUT normalerweise mit dem Monitor verbunden.

Der Grund für die Auftrennung von Standard Ausgabe und Standard Fehlerausgabe ist einfach der, daß wir diese Kanäle oftmals umleiten. Und eine Umleitung sorgt natürlich auch dafür, daß die Ausgabe jetzt nicht mehr auf dem Schirm erscheint. Käme es jetzt zu einem Fehler, so würden wir es nicht mitbekommen, weil die Ausgabe nicht sichtbar ist. Aus diesem Grund gibt es die separate Fehlerausgabe, die dafür sorgt, daß Fehlerausgaben immer noch auf dem Bildschirm zu lesen sind, auch wenn die Ausgabe umgeleitet wurde.
Umleitungen
Die Shell verwaltet die Ein- und Ausgabekanäle. Sie ist es auch, die diese Kanäle umleiten kann. Das Programm selbst merkt von dieser Umleitung nichts, es schreibt weiterhin auf die Standard Ausgabe und liesst von der Standard Eingabe. Die Shell bietet uns vier Möglichkeiten der Umleitungen. Zwei für die Eingabe und zwei für die Ausgabe:
Programm > Datei
Das Programm leitet seine Standard Ausgabe in die Datei um, statt sie auf den Bildschirm zu schreiben. Existiert die Datei schon, so wird sie überschrieben, existiert sie noch nicht, so wird sie neu angelegt.
Programm >> Datei
Das Programm leitet seine Standard Ausgabe in die Datei um, statt sie auf den Bildschirm zu schreiben. Existiert die Datei schon, so wird die Ausgabe hinten an die bestehende Datei angehängt, existiert sie noch nicht, so wird sie neu angelegt.
Programm < Datei
Das Programm ließt seine Eingabe aus der Datei statt von der Tastatur.
Programm &lt&lt EOM
...
EOM

Das Programm ließt seine Eingaben statt von der Tastatur aus dem Block zwischen den beiden EOM Marken. Dabei dürfen diese Marken beliebige Worte sein, es gilt immer vom ersten bis zum zweiten Auftreten der Marke. Diese Konstruktion wird „here-document“ genannt und findet Anwendung fast ausschließlich in der Scriptprogrammierung.
Manchmal ist es auch sinnvoll oder gewünscht, den Fehlerausgabekanal umzuleiten. Das ist über die Nennung seiner Kenn-Nummer vor dem Umleitungssymbol möglich. So würde die Anweisung
Programm 2> Fehlerprotokoll
die Fehlerausgabe des Programms in die Datei Fehlerprotokoll umleiten. Selbstverständlich ist das auch mit 2 Umleitungssymbolen (anhängend) möglich.
Und in einigen Fällen sollen beide Ausgabekanäle (STDOUT und STDERR) doch in eine Datei umgeleitet werden. Dazu kann man beide Kanäle zu einem zusammenfassen, der dann umgeleitet wird. Das geschieht mit der kryptischen Anweisung 2>&1. Aber vorsicht, um wirklich beide Kanäle in eine Datei umzuleiten muß die Bündelung nach der eigentlichen Umleitung vorgenommen werden:
Programm > Datei 2>&1
Diese Anweisung bündelt die Kanäle 2 und 1 (STDERR und STDOUT) und leitet beide in die Datei um.
Verkettung (piping)
Wenn wir jetzt zwei Programme haben, von denen das zweite die Ausgabe des ersten weiterverarbeiten sollte, so könnten wir jetzt die Ausgabe des ersten Programms in eine Datei umleiten und dann das zweite Programm aufrufen und seine Eingabe aus der Datei lesen lassen:
Programm1 > Datei
Programm2 < Datei

Das können wir auch ohne den Umweg über die Datei haben, indem wir zwei Programme direkt miteinander verbinden. Genauer gesagt verbinden wir die Standard-Ausgabe des ersten Programms mit der Standard-Eingabe des zweiten.
Dazu benutzen wir das Symbol | so daß wir einfach nur schreiben müssen:
Programm1 | Programm2
Das läßt sich beliebig fortsetzen, es ist also möglich, auch mehrere Programme hintereinanderzuhängen.
xargs
Das Programm xargs bietet eine Möglichkeit, die stark an die Kommandosubstitution erinnert. Hauptsächlich wird dieses Programm in Shells benötigt, die keine Substitution bieten, aber es gibt auch Fälle, in denen mit xargs elegantere Lösungen möglich sind, als mit der Kommandosubstitution.
xargs führt ein beliebiges Kommando aus, und gibt diesem Kommando als Parameter das mit, was xargs von der Standard-Eingabe gelesen hat. In einer Pipe ist es also möglich, daß ein Programm seine Ausgaben an xargs weiterleitet und xargs führt dann ein anderes Programm aus, das mit eben der Ausgabe des ersten Programms als Parameter bestückt wird. Ein simples Beispiel:
Wir haben eine Datei mit Namen Liste, die folgenden Inhalt hat:
datei1
datei2
datei3 datei4
datei5 /home/irgendwer

Jetzt rufen wir folgenden Befehl auf:
cat Liste | xargs cp
Der Befehl cat Liste gibt den Inhalt der Datei Liste auf die Standard-Ausgabe aus. Diese ist aber mit der Standard-Eingabe von xargs cp verbunden. xargs ruft also den Befehl cp auf und gibt ihm das mit, was es selbst von der Standard-Eingabe gelesen hat – also in unserem Fall den Inhalt der Liste. Zeilentrenner werden dabei wie Leerzeichen interpretiert. xargs ruft also folgenden Befehl auf:
cp datei1 datei2 datei3 datei4 datei5 /home/irgendwer
Den selben Effekt hätten wir mit Kommandosubstitution mit folgender Zeile erreichen können:
cp ’cat Liste’
Der Vorteil von xargs liegt darin, daß beliebig lange Ergebnisse mitgegeben werden können, weil xargs die Parameterkette aufteilt und das Programm entsprechend oft hintereinander aufruft. Die Kommandosubstitution kann das nicht und stößt irgendwann an die Grenzen der erlaubten Kommandolänge.
xargs kennt noch viele verschiedenen Kommandozeilenparameter, die aber für die LPI-101 Prüfung eher irrelevant sind.
Zwischensicherung
Die Ausnutzung komplexer Pipekonstruktionen erfordert es oft, daß einzelne Zwischenschritte während des Ablaufs in eine Datei gespeichert werden. Dazu gibt es das Programm tee, das einfach seine Standard-Eingabe auf seine Standard-Ausgabe weitergibt und daneben aber auch den Datenstrom in eine Datei zwischenspeichert. Es handelt sich also um eine Art T-Stück in einer Pipe (Rohrleitung) – daher stammt auch der Name.
Das folgende Konstrukt gibt ein Beispiel für die Anwendung:
Programm1 | tee Datei1 | Programm2 | tee Datei2 | Programm3 > Datei3

Das Programm1 schickt seine Ausgabe an das Programm tee, das sie dann in die Datei1 schreibt, aber gleichzeitig auch wieder an das Programm2 weitergibt. Dieses Programm gibt wiederum seine Ausgabe auf eine weitere Instanz von tee weiter, welches sie wieder in die Datei2 schreibt und an das Programm3 weiterleitet. Das dritte Programm schließlich speichert sein Ergebnis in der Datei3. Wir haben also alle Zwischenergebnisse einzeln gespeichert, also das gleiche Ergebnis, als hätten wir geschrieben:
Programm1 > Datei1
Programm2 Datei2
Programm3 Datei3

Zurück zu 1.103 GNU und Unix Kommandos bzw. Linux Zertifizierungen LPIC-1 [101]: Unterlagen.

Alle Artikel zur LPIC unterliegen der GNU Free Documentation License.

Weblinks:
LINUX MAN PAGES ONLINE

(859)


History

5 Gedanken zu „1.103.4 Unix Streams, Pipes und Umleitungen“

  1. danke, hat mir schon geholfen. Ich reit ja auch ungern auf den Begrifflichkeiten herum, aber für die Ausarbeitung geht das leider nicht anders. Außerdem, wie du bereits gesagt hast, hilft es ja einem tieferen Verständnis. Langfristig werd ichs aber wohl auch nicht anders machen als du.. 😉

  2. Hallo, ich hätte da mal ne kleine Frage für eine Ausarbeitung in Datenkommunikation (WI 4tes Semester). Kann man sagen, dass der Standartausgabekanal im Grunde auch eine Pipe ist, sozusagen die Standartpipe? Denn mit der Pipe kann ich ja den Datenstrom eines Bash-Befehls der im Grunde an den Standartausgabekanal wandert an einen anderen Befehl zur Weiterverarbeitung „umlenken“.. Oder versteh ich das jetzt falsch?

    1. Pipeline hin pipeline her – Verbindungen mehrerer pipes werden so bezeichnet. Zu bedenken ist bei deiner Sichtweise, dass mit dem Zeiger der pipe auf den pipe inode, also auf ein Paar an file descriptoren gezeigt wird. Ich erinnere mich aber gerade an „unbenannte und benannte pipes“ – ach ja, da ist ja die gute Erläuterung, die dir vielleicht weiter hilft, denn ich bin momentan etwas weg von dieser Materie: 4.8 Prozesskommunikation und ich bin eher pragmatisch orientiert, weshalb ich mir über mögliche Bezeichnungen noch kaum Gedanken machte. Sicher kann das aber nützlich sein, um zu einem besseren Verständnis zu gelangen. Ich verwende pipes aber einfach, wenn ich sie brauche, that’s it. 😉

  3. Excellent site, nützliche Informationen. Vielen Dank für dieses großartige Nachricht – ich werde Sie sicher, dass Sie Ihr Blog oft mehr ….

Schreibe einen Kommentar zu Wartenberg Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert