Was ist der Zweck von "Abschlag"?

19304
R Moog

Alle Verwendungen, die teeich je gesehen habe, waren so:

 do_something | tee -a logfile 

Oder:

do_something_else | tee logfile 

Ist teefür diejenigen, erfunden, die Sie nicht wissen können, das gleiche tun mit Shell Rohr Umleitungen? Sowie:

do_something >> logfile 

Oder:

do_something_else > logfile 

Es ist praktisch das gleiche und es sind weniger Keyboard-Hits erforderlich, um die Tastatur zu tippen. Welche verborgenen Funktionen sehe ich nicht tee?

87
Wie wurde dies nicht von der ersten Zeile der Manpage * "... und Standardausgabe und Dateien schreiben" * beantwortet? Die Antworten sind interessant, aber wenn man allgemein darüber spricht, wie Pfeifen nützlich sind, wird das Q-Thema nur zu breit * und scheint vielleicht zu schließen. Xen2050 vor 5 Jahren 61
@ Xen2050 Eine Frage kann nicht für eine zu breite Antwort verantwortlich gemacht werden. Die Frage ist sehr spezifisch, ebenso wie die aktuelle [höchstbewertete Antwort] (https://superuser.com/a/1356843/179350). Jon Bentley vor 5 Jahren 3
@JonBentley die Frage klingt nicht wie * "ein spezifisches Problem mit genügend Details, um eine adäquate Antwort zu finden" * (wie der Schließdialog liest). Es klingt wie folgt: * "Wenn Ihre Frage von einem ganzen Buch beantwortet werden könnte oder viele gültige Antworten hat (aber keine Möglichkeit festzustellen, welche - wenn überhaupt - richtig sind), ist sie wahrscheinlich zu breit für unser Format." * (Quelle: das [Help Center] (https://superuser.com/help/closed-questions)) Xen2050 vor 5 Jahren 1
@ Xen2050 Lesen wir die gleiche Frage? Es scheint mir sehr spezifisch zu sein - was ist der Unterschied zwischen T-Stück und Pfeife? Es wurde ausreichend mit zwei Sätzen beantwortet. Weit weg von einem ganzen Buch. Die Tatsache, dass einige Antworten sich für eine Tangente entscheiden *, hat nichts mit dem Umfang der Frage zu tun. Jon Bentley vor 5 Jahren 4
@ JonBentley: Lesen wir die gleiche Frage? Art von Art * von Moog * impliziert * eine ziemlich gut fokussierte Frage - was ist der Unterschied zwischen "tee" * und ** I / O-Umleitung **? * Die Tatsache, dass "Shell *** Pipe **" heißt. Umleitungen * wie ">" und ">>" sind kein Vorteil, und es ist ein Argument für das Schließen als unklar. Tatsächlich werden jedoch mehrere Fragen gestellt: "Was ist der Zweck von" Abschlag "?", "Wird Abschlag für diejenigen erfunden, die nicht wissen, dass Sie das gleiche mit Rohrleitungsumleitungen tun können?" Und "Was sind verborgene Funktionen für mich?" nicht in "tee" sehen? ". Mindestens zwei dieser Fragen sind zu umfassend. G-Man vor 5 Jahren 0
@ G-Man Du musst dich um diese Interpretation kümmern. Es ist offensichtlich, dass das grundlegende Jon Bentley vor 5 Jahren 0
Ich muss „meinen Weg gehen, um diese Interpretation zu machen“? Huh Ich zitiere! *** G-Man vor 5 Jahren 0

10 Antworten auf die Frage

241
Eugen Rieck

Was Sie nicht sehen, ist, dass do_something | tee -a logfiledie Ausgabe in logfile und stdout eingefügt wird, während do_something >> logfilesie nur in der Protokolldatei gespeichert wird.

Der Zweck von teeist es, ein Szenario mit einer Eingabe und mehreren Ausgaben zu erzeugen - genau wie bei einer "T" -Kreuzung.

BEARBEITEN

Es gab Kommentare dazu, wie teeeine mehr scheinlose Verwendung von möglich ist sudo. Dies ist neben dem Punkt: cat, ddoder vielleicht besser bufferbieten diese Möglichkeit mit einer besseren Leistung, wenn Sie die mehrere Ausgänge nicht brauchen. Verwenden Sie teefür das, was es entwickelt wurde, nicht für das, was es auch "tun kann".

Mehrfachausgabe ist der Schlüssel. `tee` kann sogar mehrere Argumente annehmen und in viele Dateien gleichzeitig schreiben. Kamil Maciorowski vor 5 Jahren 37
Ich würde es ein T-Stück * Pipe Fitting * nennen, nicht eine Kreuzung (wie bei einer Straßenkreuzung?). Stuff kommt auf eine Art und Weise und geht in beide Richtungen. user20574 vor 5 Jahren 20
Selbst nachdem Sie "T" gekreuzt hatten, kam mir nicht sofort der Gedanke, dass der Befehl es buchstäblich buchstabiert Sirap vor 5 Jahren 0
Oh, es sollte wie eine T-Kreuzung sein? Ich nahm an, dass es sich um einen Bezug zum Golf-Tee handelte. Anon vor 5 Jahren 0
Sie können `sudo` auch nicht verwenden, wenn Sie auf eine Datei umleiten, für die Sie keine Berechtigungen haben, während Sie` sudo` immer für `tee` verwenden können. Fanatique vor 5 Jahren 1
Wie würde ich "cat" auf einfache Weise anstelle von "tee" verwenden, z. B. in "echo /var/work/core.%p |" Sudo tee / proc / sys / kernel / core_pattern`? `echo /var/work/core.%p | sudo cat> / proc / sys / kernel / core_pattern` funktioniert nicht, da die Weiterleitung von der Nicht-Sudo-Shell verarbeitet wird. Wie bei `dd`,` echo /var/work/core.%p | sudo dd von = / proc / sys / kernel / core_pattern` funktioniert, aber `dd` ist oft ein übermächtiges Werkzeug, das großen Schaden anrichten kann, insbesondere unter` sudo`. Was "Buffer" angeht, ist es in keinem der RedHat- oder Ubuntu-basierten Distributionen, die ich zur Hand habe (oder MacOS), standardmäßig installiert ... Digital Trauma vor 5 Jahren 7
... echo /var/work/core.%p | sudo sh -c "cat> / proc / sys / kernel / core_pattern" funktioniert, obwohl ich denke, dass das zusätzliche "sh -c" kaum elegant ist Digital Trauma vor 5 Jahren 0
@DigitalTrauma `echo /var/work/core.%p | sudo / bin / cat> / proc / sys / kernel / core_pattern` funktioniert einwandfrei - Ihre Befehlszeile verwendet die Shell-interne Version von cat (nicht jedoch die Shell-interne Version von tee). Außerdem haben sudo tee und sudo dd genau das gleiche Potenzial zum Zerstören. Bei einem neuen Ubuntu ist "audo apt install buffer" eine der "Muss-Anpassungen" -Anpassungen, da "sudo buffer" Wunder bewirken kann, wenn Sie beispielsweise ein ffmpeg-Protokoll auf eine Festplatte schreiben. Am wichtigsten war mein Punkt, dass die "sudo" -Verwendung von "tee" nicht das ist, was es besonders macht - die 1: n-Beziehung zwischen rein und raus ist. Eugen Rieck vor 5 Jahren 0
@EugenRieck Ich verstehe, was die 1: n-Beziehung zwischen in: out als primärer Funktion ist. In dieser Situation funktionieren für mich jedoch weder die eingebaute "Katze" noch die "/ bin / cat". Es spielt keine Rolle, wo "cat" herkommt - das ">" wird immer noch von der obersten (nicht sudo) Shell gehandhabt. Der Vorteil von "tee" gegenüber "cat" ist in dieser Situation, dass die Ausgabedatei als Befehlszeilenparameter (und nicht als Weiterleitung) übergeben werden kann. `dd` ist sicherlich eine gangbare Option, obwohl ich immer noch` tee` dafür bevorzugen würde Digital Trauma vor 5 Jahren 3
@EugenRieck Welche Shell hat "cat" und "tee" als Builtins? Und welche Version von `Sudo` kann Shell Builtins ausführen? wjandrea vor 5 Jahren 3
@wjandrea BASH auf Ubuntu 18.04 hat "cat", aber nicht "tee" gemäß man 7 "bash-builtins" Eugen Rieck vor 5 Jahren 0
@Eugen Wo in [der Manpage] (http://manpages.ubuntu.com/manpages/bionic/man7/bash-builtins.7.html) heißt das? wjandrea vor 5 Jahren 0
@EugenRieck verwendet `sudo cat> ...` funktioniert _nicht_, und _cannot_ funktioniert nicht, es sei denn, Ihre Shell (die die Befehlszeile parst), hat die Berechtigung, in die Datei zu schreiben. Das `> ...` wird von der Shell analysiert, es wird _nicht_ der Anwendung als Argument übergeben. Es hat nichts mit dem Einbauen zu tun. Attie vor 5 Jahren 3
119
bertieb

Tee ist nicht nutzlos

Vielleicht wussten Sie das überhaupt? Wenn nicht, lies weiter! Wenn Sie wissen, wie es funktioniert, aber nicht sicher sind, warum es existiert, fahren Sie mit dem Ende fort, um zu sehen, wie es mit der Unix-Philosophie passt.

Was ist der Zweck von tee?

Im einfachsten Fall nimmt es Daten zur Standardeingabe und schreibt diese in die Standardausgabe und eine (oder mehrere) Dateien. Es wurde mit einem Sanitär-T-Stück verglichen, indem es einen Eingang in zwei Ausgänge (und zwei Richtungen) aufteilt.

Beispiele

Nehmen wir Ihr erstes Beispiel:

do_something | tee -a logfile 

Dadurch wird die Ausgabe von do_somethingund an die Protokolldatei angehängt, während sie dem Benutzer ebenfalls angezeigt wird. Tatsächlich hat die Wikipedia-Seitetee dies als zweites Beispiel:

So können Sie die Ausgabe eines Befehls anzeigen und an eine vorhandene Datei anhängen:

 lint program.c | tee -a program.lint 

Dies zeigt die Standardausgabe des Befehls lint program.c am Computer an und hängt gleichzeitig eine Kopie davon am Ende der Datei program.lint an. Wenn die Datei program.lint nicht vorhanden ist, wird sie erstellt.

Das nächste Beispiel hat eine andere Verwendung: Eskalation von Berechtigungen :

So erlauben Sie die Eskalation von Berechtigungen:

cat ~/.ssh/id_rsa.pub | ssh admin@server "sudo tee -a /root/.ssh/authorized_keys2 > /dev/null" 

In diesem Beispiel wird gezeigt, dass tee verwendet wird, um eine inhärente Einschränkung des sudoBefehls zu umgehen . sudokann die Standardausgabe nicht an eine Datei übergeben. Durch das Ablegen des Standard- /dev/nullAusgangsstroms unterdrücken wir auch die gespiegelte Ausgabe in der Konsole. Der obige Befehl gewährt dem aktuellen Benutzer Root-Zugriff auf einen Server über ssh, indem der öffentliche Schlüssel des Benutzers in der Liste der Schlüsselberechtigungen des Servers installiert wird.

Oder möchten Sie vielleicht die Ausgabe eines Befehls übernehmen, diesen irgendwo schreiben und auch als Eingabe für einen anderen Befehl verwenden?

Sie können den Befehl tee auch verwenden, um die Ausgabe eines Befehls in einer Datei zu speichern und dieselbe Ausgabe als Eingabe an einen anderen Befehl umzuleiten.

Der folgende Befehl erstellt eine Sicherung der Crontab-Einträge und übergibt die Crontab-Einträge als Eingabe an den sed-Befehl, der die Ersetzung übernimmt. Nach der Ersetzung wird es als neuer Cron-Job hinzugefügt.

$ crontab -l | tee crontab-backup.txt | sed 's/old/new/' | crontab – 

(Gutschrift für Beispiele zur Verwendung des T-Befehls )

Tee arbeitet mit der Unix-Philosophie:

Schreiben Sie Programme, die eine Sache tun und es gut machen. Schreibe Programme, um zusammenzuarbeiten. Schreiben Sie Programme, um Textströme zu verarbeiten, da dies eine universelle Schnittstelle ist.

(Anerkennung der Grundlagen der Unix-Philosophie )

tee passt zu all diesen:

  • Es macht eines: Es erstellt eine zusätzliche Kopie der Eingabe
  • Es funktioniert mit anderen Programmen, da es der Kleber ist (oder, wenn Sie es bevorzugen, ein T-Klempnerstück), das andere Programme wie in den obigen Beispielen zusammenarbeiten lässt
  • Dies geschieht durch Manipulieren eines Textstroms, der bei der Standardeingabe angegeben wird
@Joe: `sudo tee -a` ist wahrscheinlich eine neuere Neuerung (ich habe es zum ersten Mal in Ubuntu-Guides / Wikis gesehen, vor allem für das Einstellen von` / proc / sys`), weil der Wechsel zu Ubuntu war, als ich zu einem `Sudo` wechselte basiertes System (wie Ubuntu standardmäßig konfiguriert ist), anstatt `su` mit einem Root-Passwort zu verwenden). Ich denke "tee" geht vor "sudo" vor, es ist also kein Grund dafür, dass "tee" existiert. Sie brauchen dafür nicht "tee", es ist einfach kürzer als interaktiv zu tippen als "sudo sh -c" cat> output "". Peter Cordes vor 5 Jahren 3
Mit modernen Muscheln wie Bash können Sie zwei Pipelines wie "foo |" füttern tee> (pipe2) | pipe1`. Oder ein anderer Spaß ist `ffmpeg ... | & tee / dev / tty | sed 's /.* \ r //> encode.log`, um Statuszeilenaktualisierungen interaktiv auf dem tty anzuzeigen, während "Zeilen" entfernt werden, die mit Wagenrücklauf anstelle von Zeilenvorschub für die tatsächliche Protokollierung enden. (dh die Statuszeilenaktualisierungen herausfiltern). Im Allgemeinen können Sie ein "tee / dev / tty" als Debug-Print an einer beliebigen Stelle in einer Pipeline anbringen. Peter Cordes vor 5 Jahren 1
Es ist weniger eine Einschränkung von Sudo, um die Sie arbeiten, und eher eine Einschränkung der Interpretation der Shell durch>. Wenn Sie einen Befehl mit Sudo ausführen, wird dessen Standardausgabe an Ihr Shell-Programm zurückgesendet, und weitere Weiterleitungen mit> werden mit den Berechtigungen der Shell ausgeführt. Wenn Sie mit erhöhten Berechtigungen schreiben möchten, müssen Sie den erhöhten Teil der Pipeline haben, der das Schreiben übernimmt. Es gibt viele Möglichkeiten, dies zu tun, je nachdem, welchen Effekt Sie erzielen. Wenn Sie> etwas wie 'sudo bash -c "Befehl> outfile"' wirklich verwenden möchten, wird dies erledigt. Perkins vor 5 Jahren 2
Genau, @Perkins. Die Shell analysiert das `>` und richtet die Umleitung ein, bevor sudo 'exec' erhält, also ist es definitiv keine Einschränkung von sudo, dass es nicht mit Dingen umgeht, die es nie sieht. :) Ich versuche normalerweise, dies als "Sudo-Workflow" oder einen ähnlichen Begriff zu bezeichnen, wenn ich es erkläre, anstatt Sudo selbst zu beschreiben. dannysauer vor 5 Jahren 0
`sudo tee -a` ist IMHO ein Missbrauch von tee. Verwenden Sie "sudo cat", "sudo dd" oder (in vielen Fällen mit der besten Leistung) "sudo buffer", wenn Sie nicht mehrere Ausgänge benötigen. Eugen Rieck vor 5 Jahren 0
69
Attie

Es ist praktisch das gleiche und es sind weniger Keyboard-Hits erforderlich, um die Tastatur zu tippen.

Es ist überhaupt nicht das Gleiche ...

Das Folgende scheint etwas gleichwertig zu sein, aber nicht:

$ echo "hi" > test.txt 
$ echo "hi" | tee test.txt hi 

Der entscheidende Unterschied besteht darin, dass erstere die Daten nur in die benannte Datei geschrieben hat, während letztere wie unten gezeigt hiin das Terminal ( stdout) und die benannte Datei geschrieben hat:

redirect vs tee


teeErmöglicht das Schreiben der Daten in eine Datei und deren Verwendung in einer fortlaufenden Pipeline, sodass Sie nützliche Dinge erledigen können, z.

grep '^look ' interesting_file.txt \ | tee interesting_lines.txt \ | sort 

Oder Sie können in eine Datei mit erhöhten Berechtigungen schreiben, ohne der gesamten Pipeline erhöhte Berechtigungen zu erteilen (hier echowird der Benutzer ausgeführt, während er teein die Datei schreibt als root):

echo 0 \ | sudo tee /proc/sys/net/ipv4/ip_forward 

Mit teekönnen Sie in viele Dateien schreiben ( und stdout ):

echo "hi" \ | tee a.txt b.txt 

Es ist auch möglich, execmit teezu verwenden, um die gesamte Ausgabe eines Skripts in einer Datei aufzuzeichnen, während ein Beobachter ( stdout) trotzdem die Daten sehen kann:

exec > >( tee output.log ) 
Nicht zu vergessen `exec>> (tee" $ LOGFILE ") 2> & 1` in einem Bash-Skript, das es dem Skript ermöglicht, stdout und stderr an beide, stdout und die durch` $ LOGFILE 'angegebene Datei auszugeben. rexkogitans vor 5 Jahren 2
@rexkogitans 2> & 1 ist diese Cmd-Batch-Syntax nicht? dmb vor 5 Jahren 0
@dmb: Es ist Shell-Syntax für "Sende stderr (= 2) an dieselbe Stelle wie stdout (= 1)" psmears vor 5 Jahren 0
@rexkogitans Es war wirklich eine faire Frage, ich kann nicht wirklich wissen, dass Sie "Windoze" seit einem Jahrzehnt nicht benutzt haben. Ich verwende '2> & 1', um die Ausgabe zu löschen und die Textdateien in Windows anzuzeigen. dmb vor 5 Jahren 0
@dmb Es tut mir leid für unhöflich. Es geht um den Kommentar von psmears. Offensichtlich hat Windows hier den Unix-Stil übernommen. rexkogitans vor 5 Jahren 1
Sie sollten Ihre Diagramme wirklich so bearbeiten, dass der Befehl unten, "tee" oben und die beiden Ausgänge auf beiden Seiten wie ein T ... Peter A. Schneider vor 5 Jahren 0
Technisch werden die Daten in beiden Fällen in STDOUT (Dateihandle 1) geschrieben. Es ist nur so, dass bei der Weiterleitung der STDOUT von "echo" durch die Shell mit einer Datei verbunden ist, während im Fall der Pipeline der STDOUT von "tee" mit dem Terminal verbunden ist. Dies ist eine gute Antwort auf einer technischen Website. ;) dannysauer vor 5 Jahren 0
26
tjt263

Dies ist ein Abschlag:

Eine T-förmige Rohrverschraubung. Es hat einen Einlass und zwei separate Auslässe.
Mit anderen Worten, es teilt ein Rohr in zwei Teile; wie eine Gabelung auf der Straße.

In ähnlicher Weise gibt teees eine Pipe ( |), mit der Sie Ihre Standardeingabe auf zwei separate Ausgänge umleiten können.


Beispiel
Sagen Sie zum Beispiel, Sie geben ein ls /.
Sie erhalten eine Ausgabe, die ungefähr so ​​aussieht:

Applications Network Users bin dev net private tmp var Library System Volumes cores etc home opt sbin usr 

Leiten Sie die Ausgabe in eine Textdatei um, ls / > ls.txtund in der Shell wird keine Ausgabe nur in der resultierenden Textdatei angezeigt.

Möchten Sie die Ausgabe sehen UND gleichzeitig an eine Textdatei übergeben?
Fügen Sie ein a teezu Ihrer Pipe hinzu ( |) dh:ls / | tee ls.txt


Vergleichen Sie die beiden:

ls / > ls.txt ls / | tee ls.txt 
+1 für ein Bild, das bekanntlich mehr als tausend Worte wert ist Sergiy Kolodyazhnyy vor 5 Jahren 4
Wenn Sie sich für ein T-Stück aus einem Gartenschlauch entschieden hätten, hätten Sie Doug McIlroys ursprüngliche Metapher genau genommen. JdeBP vor 5 Jahren 0
@JdeBP Sorry, ich habe keine Ahnung, wer das ist. Ist er der ursprüngliche Autor des Dienstprogramms oder etwas? Der Datenfluss und der physikalische elektrische Strom werden oft mit hydraulischen Systemen verglichen, aber das wissen Sie wahrscheinlich. Jedenfalls habe ich diesen Stil gewählt, um ihn super einfach zu halten. Ich wollte das eigentlich tun, um es mir bekannt zu machen, aber die Gartensorte hat eher eine Y-Form und / oder optisch komplizierte Anhänge zum Anbringen von Zubehör usw. Es ist im Wesentlichen dasselbe. tjt263 vor 5 Jahren 0
M. Douglas McIlroy, Autor von [diesem berühmten Memo] (https://www.bell-labs.com/usr/dmr/www/mdmpipe.html), der [arbeitete bei Bell Labs] (https: // s3-us) -west-2.amazonaws.com/belllabs-microsite-unixhistory/streams.html) und [überreden Ken Thompson, Pipes in Unix zu setzen] (https://s3-us-west-2.amazonaws.com/belllabs-microsite) -unixhistory / sohedid.html). JdeBP vor 5 Jahren 1
18
LPChip

Nein. Sie erwähnen eines der wenigen Beispiele, bei denen Sie tatsächlich mithilfe von Operatoren >und zur Datei umleiten >>können.

Aber Tee kann noch viel mehr. Weil Sie zu ihm pfeifen, können Sie zu etwas anderem pfeifen.

Ein gutes Beispiel ist auf der Wikipedia-Seite aufgeführt :

find "4DOS" wikipedia.txt | tee 4DOS.txt | sort > 4DOSsorted.txt 

Grundsätzlich können Sie zu T-Stück pfeifen, sodass Sie dann von T-Stück zu etwas anderem leiten können. Wenn Sie nur eine Protokolldatei schreiben möchten, dann brauchen Sie T-Stück wirklich nicht.

17
UTF-8

teeist alles andere als nutzlos. Ich benutze es die ganze Zeit und bin froh, dass es existiert. Dies ist ein sehr nützliches Werkzeug, wenn Sie eine Pipeline haben, die Sie aufteilen möchten. Ein sehr einfaches Beispiel ist, dass Sie über ein Verzeichnis verfügen $d, das Sie tarieren möchten, und Sie möchten auch ein Hashing durchführen, da Sie (wie ich) paranoid sind und nicht darauf vertrauen, dass das Speichermedium die Daten zuverlässig speichert. Sie könnten es zuerst auf die Festplatte schreiben und dann hashieren, aber das würde fehlschlagen, wenn das Archiv beschädigt wird, bevor es gehasht wird. Außerdem müsstest du es lesen und wenn du mit Dateien arbeitest, die mehrere hundert GB groß sind, wirst du wissen, dass du sie wirklich nicht mehr lesen willst, wenn es nicht sein muss.

Also was ich mache ist einfach das:

tar -c "$d" | tee >(sha256sum) >(cat > "$d"".tar") > /dev/null 

Es erstellt den Teer-Ball und leitet ihn an ein T-Stück, das dann zu zwei Sub-Shells geleitet wird, von denen einer in einen Hash-Zustand und in den anderen Teil auf die Festplatte geschrieben wird.

Es ist auch großartig, wenn Sie mehrere Vorgänge an einer großen Datei ausführen möchten:

< file.tar.gz tee >(sha256sum) >(tar -xz) /other/storage/location/file.tar.gz > /dev/null 

Liest die Datei einmal ein, hasht sie (damit Sie überprüfen können, ob sie noch so ist, wie sie sein sollte), extrahiert sie und kopiert sie an einen anderen Ort. Sie müssen es nicht dreimal lesen.

Nitpick: `tee` erstellt keine Subshells; Die aufrufende Shell führt "sha5sum" und "cat" aus und verbindet ihre Ausgabe mit Dateideskriptoren, die an "tee" übergeben werden. Auch eine sinnlose Verwendung von "Katze"; Sie können die Eingabeumleitung verwenden, um `tee` direkt von` file.tar.gz` lesen zu lassen. chepner vor 5 Jahren 3
@chepner Sie haben recht mit der ersten Interjektion, aber mit der zweiten sind Sie völlig falsch. Ich schreibe meine Pipelines in der richtigen Reihenfolge, daher ist das Ablesen der Eingabe auf der rechten Seite für die Lesbarkeit schlecht, und dies ist meiner Methode eindeutig objektiv unterlegen und keine subjektive Präferenz von mir. "Katze" ist Liebe. "Katze" ist das Leben. UTF-8 vor 5 Jahren 0
Sie können auch `<file.tar.gz tee> (sha256sum) ...` schreiben, wenn Sie sich Gedanken über die lexikalische Reihenfolge der Weiterleitungen machen. Das ändert nichts an der Tatsache, dass kein völlig separater Prozess erforderlich ist, nur um eine einzelne Datei an `tee 'zu übergeben. chepner vor 5 Jahren 6
@chepner Cool, danke! Heute etwas gelernt. :) UTF-8 vor 5 Jahren 1
Nutzloser Einsatz von `dd`. Verwenden Sie `/ other / storage / location / file.tar.gz` als Argument für` tee`, damit es direkt in die Datei und nicht in eine Pipe zu einem anderen Prozess geschrieben wird. Gleiches Problem mit dem ersten Beispiel: Sie werden überhaupt nicht lesbar, wenn Sie die Ausgabe über `cat>" $ d ".tar` leiten. Warten Sie, Sie haben tatsächlich die Anführungszeichen auf `` .tar '`, aber die Erweiterung von` $ d` ist nicht in Anführungszeichen?!?) Peter Cordes vor 5 Jahren 0
@chepner, du hast mein Leben für immer verändert: O Shadow vor 5 Jahren 0
@PeterCordes, die `Katze` s ist möglicherweise kostenlos, aber `dd` meldet beim Empfang von SIGUSR1 die Übertragungsstatistik an STDERR (nützlich, wenn der Job länger dauert als erwartet). Oder ersetzen Sie entweder "pv", um die Übertragungsstatistiken am Ende an STDERR zu melden. david vor 5 Jahren 0
@david Ja. Sie können auch `status = progress` do` dd` übergeben, um Fortschrittsinformationen zu erhalten. Wenn Sie einen anderen Prozess starten, wird der Befehl natürlich etwas länger. Aber es wird nicht viel komplizierter und ich denke, mit cat ist es einfacher zu verstehen. Was kostet außerdem ein anderer Prozess genau? Ich verstehe nicht, warum das ein Kriterium ist. UTF-8 vor 5 Jahren 0
Die Kosten für das "Starten" von "Katze" sind relativ niedrig. Die Kosten für zusätzliche 100 GiB für Write + Read-Systemaufrufe verschwenden auf jeden Fall zusätzliche CPU-Zeit und Speicherbandbreite für das vorgeschlagene Beispiel einer großen Datei. Denken Sie daran, dass die Speicherbandbreite eine gemeinsam genutzte Ressource für alle Kerne ist, ganz zu schweigen von der zusätzlichen Belastung des L3-Cache durch das Kopieren. Auf einem x86 mit aktivierter Spectre + Meltdown-Reduzierung sind Systemaufrufe teurer als früher. Sie benötigen eine messbare Menge zusätzlicher CPU-Zeit im Verlauf dieser Kopie. Auch "> (cat> foo)" ist nicht einfacher zu verstehen als "foo", IMO. Peter Cordes vor 5 Jahren 1
@david: Unter Linux können Sie die Positionen der Dateideskriptoren von außerhalb eines Prozesses sehen, indem Sie `/ proc / PID / fdinfo / 3` verwenden. Sie können "pv" an einen bereits laufenden Prozess anschließen, um diesen zu überwachen, anstatt Daten * durch * pv zu leiten, indem Sie "pv -d 1234: 3" (PID: FD) verwenden. http://man7.org/linux/man-pages/man1/pv.1.html. Sie müssen Ihr System also nicht mit zusätzlichen Speicherkopien verlangsamen, nur für den Fall, dass Sie es überwachen möchten. Peter Cordes vor 5 Jahren 0
Dieser tar-Befehl sollte wahrscheinlich '-f-' enthalten. Wenn dieses Argument nicht angegeben ist, verwendet tar eine Umgebungsvariable (`$ TAPE`), sofern vorhanden, und verwendet dann einen kompilierten Standard, der nicht in der Manpage und nicht unbedingt als Standard definiert ist. dannysauer vor 5 Jahren 0
@dannysauer Die Manpage von `tar` habe ich angegeben. Im Abschnitt "Umgebung" wird "TAPE" wie folgt beschrieben: "Gerät oder Datei, die für das Archiv verwendet werden soll, wenn --file nicht angegeben ist. Wenn diese Umgebungsvariable nicht festgelegt ist, verwenden Sie stattdessen stdin oder stdout." Ich bin mir nicht sicher, ob das irgendwo wirklich unbestimmt ist. Ich denke, Sie können ziemlich sicher sein, dass diese Umgebungsvariable nicht gesetzt ist. UTF-8 vor 5 Jahren 0
Seltsam - auf meiner Manpage heißt es: "Andernfalls geht tar von der Standardeinstellung aus. Der Standardwert kann entweder mit der Option --show-defaults oder am Ende der tar --help-Ausgabe überprüft werden." Wie auch immer, in meiner "25 Jahre Unix sysadmin hair-out-out" Meinung sind diese vier zusätzlichen Charaktere eine viel bessere Zeit, als irgendwann einen halben Tag aufzuspüren, warum das Skript aufgrund einer Umgebung nicht funktioniert Variable auf dieser einen Maschine, die vor fünf Jahren von Larry verpatzt wurde, indem er einen halb-gebackenen Shell-Auszug aus einem Forum in / etc / profile kopierte. : D dannysauer vor 5 Jahren 0
12
studog

Nitpick on @ bertiebs Antwort lautet: Dieses Beispiel zeigt, dass tee verwendet wird, um eine inhärente Einschränkung im Befehl sudo zu umgehen. sudo kann die Standardausgabe nicht an eine Datei übergeben.

Es gibt keine inhärente Einschränkung, nur ein Missverständnis darüber, wie der Befehl verarbeitet wird.

Beispiel:

sudo echo 0 > /proc/sys/net/ipv4/ip_forward

Die aktuelle Shell analysiert die Befehlszeile. Es findet die Umleitung der Ausgabe und führt diese aus. Dann führt er den Befehl aus, der sudoden verbleibenden Befehl als Argument für den ausgeführten Befehl bereitstellt. Wenn die aktuelle Shell keine Root-Berechtigungen hat, schlägt die Ausgabeumleitung fehl.

echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward

Dies funktioniert, weil die Ausgabeumleitung auf den teeBefehl beschränkt ist, der zu diesem Zeitpunkt über Root-Berechtigungen verfügt, da er über ausgeführt wurde sudo.

sudo bash -c "echo 0 > /proc/sys/net/ipv4/ip_forward"

Dies funktioniert, weil die Shell, die die Umleitung ausführt, über Root-Berechtigungen verfügt.

Möglicherweise benötigen Sie `sudo` für den Befehl, aber nicht für die Ausgabe der Datei. Die Umleitung funktioniert einwandfrei:` sudo foo-needs-privileg> / tmp / this-output-file-doesnt` Dennis Williamson vor 5 Jahren 2
10
J-L

Wie andere Personen bereits erwähnt haben, teeschreibt das Piping-Ausgabe an den Befehl diese Ausgabe sowohl in eine Datei als auch in stdout.

Ich verwende häufig, teewenn ich die Ausgabe eines Befehls erfassen möchte, dessen Ausführung viel Zeit in Anspruch nimmt, und gleichzeitig die Ausgabe visuell prüfen möchte, wenn der Befehl sie verfügbar macht. Auf diese Weise muss ich nicht warten, bis der Befehl beendet ist, bevor ich die Ausgabe inspiziere.

Was bisher noch nicht erwähnt wurde (es sei denn, ich habe es übersehen), ist, dass der teeBefehl auch in mehrere Dateien gleichzeitig schreiben kann. Zum Beispiel:

ls *.png | tee a.txt b.txt 

schreibt alle *.pngDateien im aktuellen Verzeichnis gleichzeitig in zwei verschiedene Dateien ( a.txtund b.txt).

Tatsächlich können Sie Text in mehrere Dateien gleichzeitig teeeingeben:

$ tee --append a.txt b.txt c.txt d.txt These lines are appended to four different files, and are also written to stdout. CTRL-D 
9
Wil Young

Die häufigste Verwendung von tee ist, den Text auf dem Terminal gleichzeitig anzuzeigen, wenn Sie ihn an die Datei (oder Dateien) senden. Der Wortlaut Ihrer Frage setzt voraus, dass Sie nur Text in Protokolldateien schreiben. Ich habe Skripts, die Listen von Dateinamen oder Verzeichnisnamen schreiben, um Dateien auszulösen (um von anderen Skripten asynchron verarbeitet zu werden), und ich benutze tee, um denselben Inhalt an stdout zu senden. Alles stdout wird zu den Protokollen geleitet. Ich habe meinen Text dort, wo ich ihn haben möchte, und ich habe eine Protokolleintragsaufzeichnung, die ich aus einer einzigen Echo-Anweisung gemacht habe

tee ist auch die beste Methode unter Unix, um mehrere identische Dateien zu erstellen. Ich benutze es gelegentlich, um mehrere leere Dateien zu erstellen, wie diese ...

:|tee file01 file02 file03 
Warum nicht "anfassen"? (offensichtlicher was passiert) Attie vor 5 Jahren 5
@Attie `touch` schneidet Dateien nicht ab, wenn sie bereits vorhanden sind, sondern aktualisiert nur ihre Zeitstempel und lässt den Inhalt unverändert. aber "tee" schneidet sie ab. Das Ausführen von "rm" + "touch" unterscheidet sich von "tee" (denken Sie an Hardlinks und Symlinks). Matija Nalis vor 5 Jahren 0
Warum dann nicht '0' abschneiden? :-) Attie vor 5 Jahren 0
1
domih

Stellen Sie sich vor, Sie möchten die Ausgabe eines Befehls in eine Protokolldatei schreiben und in stdout drucken. Wenn Sie es gleichzeitig tun müssen, dann müssen Sie es tun tee.

Ein Anwendungsfall ist das Erstellen von Skripts, die den gesamten Build in stdout (z. B. für Jenkins) und wichtige Elemente gleichzeitig in eine separate Protokolldatei (für zusammenfassende E-Mails) schreiben.

Sie werden wirklich vermisst werden, teewenn Sie unter Windows ein Skript erstellen müssen. Es gibt keine teeund das ist wirklich nervig.

Ist es nicht trivial zu erstellen? Lightness Races in Orbit vor 5 Jahren 0
Mit batch / cmd ist dies nicht möglich, da Sie den Ausgabestrom eines Befehls nicht einfach aufteilen können. domih vor 5 Jahren 0
Richtig, aber wie ein dreizeiliges C ++ - Programm ... Lightness Races in Orbit vor 5 Jahren 0
Die Windows-Unxutils-Distribution enthält viele Unix-Befehlszeilentools, die im Gegensatz zu einigen Distributionen Ihre Windows-Ausführungsumgebung nicht verschmutzen. Die größte Einschränkung betrifft "Glob", was unter Unix / Linux anders funktioniert als unter Windows. "tee" gehört zu den verfügbaren Werkzeugen. cmm vor 5 Jahren 1
@LightnessRacesinOrbit Ich bin mir ziemlich sicher, dass die meisten Unix-Befehlszeilenprogramme als dreizeilige C-Programme gestartet wurden. Es war eine der wichtigsten Design-Philosophien unter Unix - winzige Tools, die * einen * Job erledigen und gut mit anderen kommunizieren. Luaan vor 5 Jahren 0
Seien Sie nicht dumm, es ist 2018. Verwenden Sie Powershell, es hat "Abschlag". Cmd war nie für ernsthaftes Scripting gedacht - dafür gab es VBS. Powershell ist das neue Skriptwerkzeug. Zugegeben, Cmd ist immer noch ziemlich mächtig, aber die Befehlszeilen-Tools sind ziemlich wenige. Luaan vor 5 Jahren 2
@Luaan Nun, genau! Daher scheint das Portieren dieser Philosophie in die Windows-Entwicklerumgebung bei Bedarf ein Kinderspiel zu sein Lightness Races in Orbit vor 5 Jahren 0