tee ist das T-Stück der Pipeline: Es liest Daten von stdin und schreibt sie gleichzeitig an stdout und in eine (oder mehrere) Dateien. Damit kannst du Output mitloggen, ohne ihn aus dem Terminal zu verlieren — und du kannst eine Pipeline an einer Stelle abzweigen lassen, ohne sie zu unterbrechen. Sein bekanntestes Killer-Pattern ist sudo tee für root-Writes, das die klassische Falle mit sudo > /etc/datei umgeht.
Was tee macht
Bildlich gesprochen ist tee ein T-Verzweigungsstück in einer Wasserleitung: Was hineinfliesst, kommt am normalen Ausgang weiter — und ein Teil zweigt seitlich ab in eine Datei. tee liest stdin, gibt alles unverändert auf stdout aus und schreibt parallel in jede übergebene Datei.
echo "Hallo Welt" | tee gruss.txtHallo WeltNach dem Aufruf existiert gruss.txt mit dem Inhalt Hallo Welt, und der Text steht im Terminal. Genau dieses doppelte Ziel — Anzeige plus Persistierung — ist der Kern von tee.
Optionen
| Option | Wirkung |
|---|---|
-a, --append | Hängt an die Datei an, statt sie zu überschreiben |
-i, --ignore-interrupts | Ignoriert SIGINT (Ctrl+C) — Pipeline läuft weiter, tee schreibt zu Ende |
-p | Diagnostiziert Schreibfehler bei Pipes (selten genutzt) |
FILE... | Mehrere Zieldateien möglich — tee a.log b.log c.log |
Der häufigste Schalter ist -a zum Anhängen — denn der Default überschreibt jede Zieldatei. Vergisst du -a, ist deine alte Logdatei nach dem ersten Aufruf weg.
Klassische Use-Cases
tee glänzt immer dann, wenn du Output gleichzeitig sehen und persistieren willst.
make 2>&1 | tee build.logDu siehst alle Compiler-Ausgaben live und hast nach dem Build eine vollständige Datei zum Nachlesen. 2>&1 leitet stderr nach stdout, sodass auch Fehlermeldungen in der Logdatei landen.
tee kann auch mehrere Ziele gleichzeitig beschreiben — selten gebraucht, aber gelegentlich nützlich, etwa um eine Datei und ein FIFO zu füttern.
ls -lh | tee verzeichnis.txt backup.txtKiller-Pattern: sudo tee für root-Writes
Das wahrscheinlich wichtigste Idiom mit tee. Folgender Befehl schlägt unter normalen Bedingungen fehl:
sudo echo "config" > /etc/myservice.confDer Grund ist subtil: Die Umleitung > wird von der eigenen Shell ausgeführt — bevor sudo überhaupt startet. Die Shell versucht also als normaler User, /etc/myservice.conf zum Schreiben zu öffnen, scheitert mit Permission denied, und sudo echo ... kommt nie zum Zuge.
tee umgeht das, weil tee selbst das Schreiben übernimmt — und das tut es als root, wenn du es mit sudo startest.
echo "config" | sudo tee /etc/myservice.conf > /dev/nullDas > /dev/null am Ende unterdrückt die Doppel-Anzeige im Terminal — wir wollen die Datei schreiben, nicht den Inhalt nochmal sehen. Mit -a hängst du an Configfiles an, statt sie zu ersetzen.
Mit -a Anhängen
Logfiles wachsen — sie werden nicht überschrieben. Das Default-Verhalten von tee ist allerdings „truncate” (Datei auf 0 Byte zurücksetzen). Für Logging ist -a Pflicht.
date | tee -a aktivität.logJeder Aufruf hängt eine neue Zeile mit dem aktuellen Timestamp an aktivität.log an — alte Einträge bleiben erhalten.
Praxis
Build mitloggen — Compiler-Output am Bildschirm und im File.
make 2>&1 | tee build.logDas 2>&1 zieht stderr in dieselbe Pipeline, sonst liefe nur stdout durch tee und Compiler-Fehler würden zwar im Terminal sichtbar, aber nicht in build.log landen. Reihenfolge ist hier wichtig: 2>&1 muss vor der Pipe stehen.
Paketinstallation dokumentieren — apt-Output für später aufheben.
sudo apt install nginx 2>&1 | tee -a install.logMit -a wird angehängt, statt überschrieben — so sammelt sich über die Zeit eine Historie aller Installationen in einer Datei. Praktisch beim Debugging, wenn ein Paket plötzlich kaputt geht und du sehen willst, was zuletzt eingespielt wurde.
Konfig als root schreiben — das sudo tee-Idiom in der Praxis.
echo "127.0.0.1 mibeon.local" | sudo tee -a /etc/hosts > /dev/nullDer Trick: sudo echo ... > /etc/hosts funktioniert nicht, weil die Shell die Redirect-Umleitung mit den eigenen Rechten öffnet, nicht mit root. sudo tee umgeht das, weil tee selbst als root läuft und die Datei direkt öffnet. Das > /dev/null unterdrückt nur die zusätzliche Terminal-Ausgabe.
Pipeline debuggen — sehen, was zwischen zwei Stages durchfliesst.
cat data.txt | grep ERROR | tee stage2.dump | wc -lstage2.dump enthält die Zwischenausgabe nach grep, und das wc -l am Ende zählt sie wie gewohnt — die Pipeline läuft unverändert weiter.
Besonderheiten
tee schreibt zu Datei UND stdout
Was selbstverständlich klingt, ist in Pipelines manchmal störend: cmd | tee log.txt | next heißt, dass next denselben Datenstrom bekommt, der auch in log.txt landet. Wenn du nur das File willst, hängst du > /dev/null an. Beim sudo tee-Pattern ist das fast immer nötig, sonst druckt das Terminal den Configinhalt nochmal nutzlos aus.
tee blockt nicht bei vollem Disk
Ein klassischer Bug-Vector: Wenn die Zieldatei nicht beschrieben werden kann (volle Disk, fehlende Rechte, Read-only-Filesystem), schreibt tee trotzdem weiter auf stdout. Die Pipeline läuft scheinbar normal — nur die Datei bleibt leer oder unvollständig. Bei kritischen Logs lohnt es sich, hinterher mit wc -l oder stat zu prüfen, ob das File wirklich Inhalt hat.
Reihenfolge der Files: schnellste Disk zuerst
Bei mehreren Zielen schreibt tee sequenziell pro Block. Wenn eine Datei auf einer langsamen Disk liegt (Netzwerklaufwerk, USB-Stick) und eine andere auf SSD, bremst der langsame Pfad die ganze Pipeline aus. Nicht oft praxisrelevant, aber bei IO-intensiven Logs einen Gedanken wert.
pipefail und tee maskieren Exit-Codes
In cmd | tee log.txt bekommt $? den Exit-Code von tee — nicht von cmd. Wenn cmd mit Fehlerstatus endet, merkst du das ohne set -o pipefail nicht. In Skripten mit tee solltest du pipefail aktivieren, sonst gehen Fehler in der Pipeline verloren und das Skript läuft falsch weiter.
Process Substitution als tee-Alternative
Bash und Zsh kennen >(...) — Process Substitution. Damit kannst du Output an mehrere Empfänger gleichzeitig schicken, ohne tee: cmd > >(gzip > out.gz) 2> >(grep ERROR > err.log). Eleganter als tee, wenn die einzelnen Ziele eigene Verarbeitungsschritte brauchen — tee ist dann nur das Bündelungswerkzeug, die Logik passiert in den Substitutionen.
Weiterführende Ressourcen
Externe Quellen
- tee(1) – Linux manual page (man7.org) — offizielle Dokumentation aller Optionen
- GNU Coreutils Manual: tee invocation — ausführliche Beschreibung im GNU-Handbuch
- Arch Wiki: Core utilities — Übersicht über tee und verwandte Werkzeuge
Verwandte Artikel
- cat – Dateien anzeigen und verbinden — Inhalte ausgeben und konkatenieren
- echo – Text und Variablen ausgeben — einfache Textausgabe als häufige tee-Quelle
- Streams und Pipes — stdin, stdout, stderr und Umleitungen verstehen
- sudo – Befehle als anderer User — der Partner für das
sudo tee-Idiom - less – Dateien blättern — interaktiv durch tee-Logs scrollen