Pipes
Text, Pipes & Filter
Das Pipe-Prinzip
Eine Pipe (das Zeichen |) verbindet zwei Befehle: Die Ausgabe (stdout) des ersten wird zur Eingabe (stdin) des zweiten. So entstehen leistungsfähige Verarbeitungsketten aus kleinen Werkzeugen. Das ist die Grundidee der Unix-Philosophie: „Schreibe Programme, die eine Sache gut machen, und lass sie zusammenarbeiten.“
Einfache Beispiele
$ ls -l | less # lange Liste seitenweise ansehen $ cat datei.txt | wc -l # Zeilen zählen $ ps aux | grep nginx # nur nginx-Prozesse zeigen
Statt eine Zwischendatei zu erzeugen, fließen die Daten direkt von Befehl zu Befehl – das ist schnell und spart Speicher.
Mehrere Pipes verketten
Du kannst beliebig viele Befehle hintereinanderschalten. Hier zählen wir, welche Benutzer am häufigsten in einer Logdatei vorkommen:
$ cat zugriff.log | grep "LOGIN" | cut -d' ' -f3 | sort | uniq -c | sort -nr
42 anna
17 bob
3 carla
Jeder Schritt verarbeitet die Daten ein Stück weiter: grep filtert, cut schneidet ein Feld heraus, sort ordnet, uniq -c zählt, sort -nr sortiert numerisch absteigend.
tee – gleichzeitig speichern und weiterleiten
Manchmal willst du ein Zwischenergebnis sehen oder speichern und trotzdem weiterverarbeiten. Das leistet tee – es schreibt die Daten in eine Datei und gibt sie zugleich an stdout weiter:
$ ls -l | tee liste.txt | wc -l # speichern UND zählen $ befehl | tee -a log.txt # -a hängt an statt zu überschreiben
Beliebt ist tee auch zusammen mit sudo, um als root in geschützte Dateien zu schreiben:
$ echo "127.0.0.1 test" | sudo tee -a /etc/hosts
Was macht eine Pipe |?
Stolperfallen & Hinweise
Eine Pipe verbindet nur stdout, nicht stderr. Fehlermeldungen rauschen an der Pipe vorbei auf den Bildschirm – willst du sie mitleiten, brauchst du 2>&1 (siehe Umleitung). Beachte außerdem: Der Exit-Status einer Pipeline ist standardmäßig der des letzten Befehls. Schlägt ein Befehl in der Mitte fehl, bleibt das leicht unbemerkt – in Skripten hilft set -o pipefail, damit auch Fehler innerhalb der Kette erkannt werden.