SelfLinux Grundlagen Einführung in die Bourne Again Shell (bash) Abschnitt 3 | SelfLinux-0.13.0

| Einführung in die Bourne Again Shell (bash) | Autor Formatierung GPL

#### 3 Pipes und Verwandtes

#### 3.1 Eingabe und Ausgabe von Daten

Programme verhalten sich meist so, dass sie bestimmte Daten aufnehmen, diese Daten auf irgendeine Weise verwenden, um schließlich wieder Daten auszugeben. Dieses Schema verdeutlicht sich noch bei interaktiven Programmen, die immer wieder Informationen vom Benutzer annehmen und ihm andere Informationen zurückliefern. Eine Shell ist ein typisches interaktives Programm. Zu diesem Zweck muß sie über einen Eingabekanal verfügen, über den sie Information aufnehmen kann. Dieser Eingabekanal existiert tatsächlich und erhält unter Linux die Bezeichnung Standardeingabe. Sie dürfen getrost bei der Vorstellung von einem Kanal oder Rohr bleiben, über das die Shell Daten entgegennimmt.

Womit aber ist die Standardeingabe verbunden? Ganz klar, üblicherweise wird dies Ihre Tastatur sein. Die Shell nimmt Zeichen für Zeichen von Ihrer Tastatur entgegen und gibt diese Zeichen auch sofort auf dem Bildschirm aus. Damit haben wir in technischer Hinsicht jedoch bereits einen großen Sprung getan, denn die Ausgabe von Zeichen auf dem Bildschirm kann selbstverständlich nicht von der Standardeingabe erledigt werden. Die Shell verfügt also über einen weiteren Kanal, der folgerichtig mit Standardausgabe bezeichnet wird. Die Standardausgabe der Shell ist üblicherweise mit Ihrem Monitor verbunden, so dass Sie die eingetippten Zeichen sehen können.

Es gibt noch einen dritten Kanal, der eine besondere Aufgabe zu erfüllen hat, der sogenannte Standardfehlerkanal. Wie der Name schon sagt, dient der Kanal zur Ausgabe von Fehlermeldungen, wenn der Programmlauf, in unserem Fall die Arbeit der Shell, aus irgendeinem Grund nicht ordnungsgemäß fortgesetzt werden konnte. Üblicherweise ist Standardfehler ebenfalls mit dem Bildschirm verbunden und schreibt daher seine Meldungen zwischen die gewöhnliche Ausgabe. Es macht jedoch Sinn, Stardardausgabe und Standardfehler voneinander zu trennen, um die Möglichkeit zu haben, gewöhnliche Ausgaben und Fehlerausgaben getrennt zu verarbeiten. Beispielsweise könnte man die Fehlerausgabe in eine Datei umlenken, um sie später zu analysieren, während, die gewöhnliche Ausgabe weiterhin über den Bildschirm läuft.

An dieser Stelle gilt es etwas Wichtiges zu verstehen: Standardeingabe, Standardausgabe und Standardfehler sind lediglich Kanäle, die mit irgendeiner Quelle und irgendeinem Ziel verbunden sein können. Standardeingabe ist nicht gleich Tastatur. Und Standardausgabe ist nicht gleich Monitor. Es gibt viele andere Quellen und Ziele, mit denen diese Kanäle verbunden werden können, wie beispielsweise Dateien oder andere Programme. Bei einer Shell macht es jedoch Sinn, Tastatur und Monitor als Eingabe und Ausgabe zu verwenden, daher ist dies die Voreinstellung.

Die drei Standardkanäle werden von Linux wie Dateien behandelt. Für geöffnete Dateien verwaltet das System eine Liste von Dateideskriptoren, die mit fortlaufenden ganzen Zahlen bezeichnet werden. Die Zahlen von 0 bis 2 sind für die drei Standardkanäle vorbelegt:

Standardeingabe | (stdin) : 0
Standardausgabe | (stdout): 1
Standardfehlerausgabe | (stderr): 2

Bei der Umlenkung der Kanäle werden wir diese Bezeichnungen noch benötigen.

#### 3.2 Datenströme für Kommandos

Standardeingabe und -ausgabe der Shell sind wenig aufregend, denn es handelt sich um die bloße Eingabe von Zeichen durch die Tastatur und deren Ausgabe auf dem Monitor.

Ebenso wie die Shell verfügen jedoch auch viele andere Programme und Kommandos über eine Standardeingabe und eine Standardausgabe. Ein hübsches Beispiel liefert uns das kleine Programm wc ("word count"), das zum Zählen von Worten, Zeilen und anderem dient. Lassen Sie uns hier durch Angabe der Option -w lediglich nach Worten zählen:

user@linux ~$ wc -w

Der übliche Prompt der Shell verschwindet. Scheinbar geschieht nichts, aber das ist auch verständlich. wc dient schließlich dem Zählen - doch was soll es hier zählen? Es wartet schlichtweg auf eine Eingabe des Benutzers. Geben wir wc etwas zu tun:

user@linux ~$ wc -w wort1 wort2

Nanu? Noch immer kein Ergebnis? Nun, wir müssen wc mitteilen, dass die Eingabe beendet ist. In diesem Fall genügt nicht das einfache Enter, da wc auch nach dem Drücken der Entertaste weitere Worte erwartet. Das Endezeichen ist hier die Kombination `STRG+``d`:

user@linux ~$ wc -w wort1 wort2 2

Aha. Sie können hier die Betätigung von `CTRL+``d` nicht erkennen, aber Sie sehen das Ergebnis: wc hat die eingegebenen Worte gezählt und gibt die Anzahl auf dem Bildschirm aus. wc verfügt also über eine Standardeingabe, die hier mit der Tastatur verbunden war, und über eine Standardausgabe, wieder verbunden mit dem Bildschirm.

Erinnern wir uns nun daran, dass die Datenströme keineswegs fest mit Tastatur und Monitor verdrahtet sind. Tatsächlich ist es sehr einfach, diese Datenströme umzuleiten. Hierfür kommt eine Reihe spezieller Symbole zum Einsatz, die wir im folgenden kennenlernen werden.

#### 3.3 Umleitung von Datenströmen

#### 3.3.1 Aus einer Datei lesen

Wir wollen, dass die Standardeingabe nicht mit der Tastatur verbunden wird, sondern mit einer Datei. Zum Beispiel möchten wir mittels wc die Anzahl der Worte in einer Datei lesen:

user@linux ~$ wc -w < datei.txt 157 datei.txt

wc hat diesmal nicht auf eine Eingabe gewartet, sondern direkt aus der Datei datei.txt gelesen. Dies wurde durch das Umlenkungszeichen < erreicht. Das folgende Bild veranschaulicht dies:

#### 3.3.2 In eine Datei schreiben

Dasselbe können wir mit der Standardausgabe unternehmen. Verbinden wir sie mit der Datei anzahl.txt und geben einige Worte ein:

user@linux ~$ wc -w > anzahl.txt wort1 wort2 wort3

Der Prompt der Shell erscheint wieder, ohne dass wir die Ausgabe von wc lesen konnten. Statt auf dem Bildschirm landete die Ausgabe in der Datei anzahl.txt, was wir mittels cat (ein Kommando, das den Inhalt von Textdateien ausgibt) leicht ersehen können:

user@linux ~$ cat anzahl.txt 3

Der Mechanismus wird durch das folgende Schaubild veranschaulicht:

#### 3.3.3 An eine Datei anhängen

Durch die vorhergehende Umleitung wird der Inhalt der Datei überschrieben, falls die Datei bereits vorhanden war. Wollen wir die neuen Daten lediglich an das Ende der Datei anhängen, benutzen wir die folgende Schreibweise:

user@linux ~$ wc -w >> anzahl.txt wort1 wort2 wort3 wort4 user@linux ~$ cat anzahl.txt 3 4

Der alte Inhalt ist erhalten geblieben.

#### 3.3.4 Fehler umleiten

Der Fehlerkanal ist dem Dateideskriptor 2 zugeordnet. Bei der Umleitung des Fehlerkanals verwenden wir nun diese interne Bezeichnung:

user@linux ~$ programm 2> error.txt

Dies ist irgendein Programm, dessen Fehlerausgabe wir in der Datei error.txt speichern wollen. Stehen in error.txt bereits andere Fehlermeldungen, die erhalten bleiben sollen, kann die folgende Schreibweise verwendet werden:

user@linux ~$ programm 2>> error.txt

Manchmal sollen alle Ausgaben, Standardausgabe und Standardfehler, in eine Datei umgeleitet werden. Hierzu können wir folgende Schreibweise verwenden:

user@linux ~$ programm > ausgabedatei 2>&1

Zunächst wird die Standardausgabe mit einer Datei verbunden. Dann wird der Standardfehlerkanal mit der Standardausgabe verbunden, so dass er ebenfalls in die Datei schreibt.

#### 3.4 Kommandos verbinden

Alles bisherige war Babykram gegen das, was jetzt kommt. Der folgende Mechanismus bringt wie kaum ein anderer die Philosophie von Unix-Betriebssystemen zum Ausdruck. Wie bereits an anderer Stelle erwähnt, ähnelt Unix (also auch Linux) einem Baukasten: Es besteht aus einer Vielzahl kleiner Elemente, die sich wundersam zusammenfügen lassen.

Der zentrale Mechanismus hierbei ist die Umlenkung der Standardausgabe eines Kommandos in die Standardeingabe eines anderen Kommandos. Dieses erreichen Sie durch die Verwendung des "Pipe"-Symbols |. Füttern wir wc einmal mit der Ausgabe eines ls:

user@linux ~$ ls | wc -w 15 user@linux ~$ ls _webseiten deepcalc gimp mp3 themes bewerbung dokumente karteikarten rcs tutorials bilder downloads linuxartikel software_liste verzeichnisse

Wie wir sehen, findet ls im aktuellen Verzeichnis genau 15 Verzeichnisse. Leiten wir seine Standardausgabe zu wc um, benutzt dieses den Input als Standardeingabe und zählt die Worte. Die Namen erscheinen dann nicht auf dem Bildschirm, wie sie es beim darauffolgenden Aufruf ohne Umleitung tun.

Auf diese Weise lassen sich beliebig viele Kommandos zusammenfügen, so dass sich häufig auch sehr komplizierte Aufgabenstellungen durch eine einzige Kommandozeile bewältigen lassen. Sie möchten beispielsweise alle Dateien in einem bestimmten Verzeichnis finden, die auf .html enden, aus diesen diejenigen herausfiltern, welche die Zeichenkette projekt enthalten, und sie in ein anderes Verzeichnis, diesmal aber mit der Endung .htm verschieben. Für diese Aufgabe können sie mehrere Kommandos verwenden, die Sie mittels mehrerer Pipes verbinden. Das gesamte Gebilde bezeichnen wir als Pipeline.