1603 Stimmen

Wie man die Ausgabe in eine Datei und stdout umleitet

In bash wird durch Aufrufen von foo jegliche Ausgabe dieses Befehls auf der Standardausgabe angezeigt.

Durch Aufrufen von foo > output wird jegliche Ausgabe dieses Befehls in die angegebene Datei umgeleitet (in diesem Fall 'output').

Gibt es eine Möglichkeit, die Ausgabe in eine Datei umzuleiten und sie gleichzeitig auf der Standardausgabe anzuzeigen?

6 Stimmen

Wenn jemand hier gelandet ist, der nach dem Erfassen von Fehlerausgaben in Datei sucht, schauen Sie sich - unix.stackexchange.com/questions/132511/… an.

9 Stimmen

Eine Anmerkung zur Terminologie: Wenn Sie foo > output ausführen, werden die Daten wirklich in stdout geschrieben, und stdout ist die Datei mit dem Namen output. Das bedeutet, dass das Schreiben in die Datei das gleiche ist wie das Schreiben in stdout. Sie fragen, ob es möglich ist, sowohl in stdout als auch in das Terminal zu schreiben.

4 Stimmen

@WilliamPursell Ich bin mir nicht sicher, ob Ihre Klarstellung die Dinge verbessert :-) Wie wäre es damit: OP fragt, ob es möglich ist, die Standardausgabe des aufgerufenen Programms sowohl in eine Datei als auch in die Standardausgabe des aufrufenden Programms zu leiten (letzteres wäre die Standardausgabe, die das aufgerufene Programm erben würde, wenn nichts Besonderes getan würde; d.h. das Terminal, wenn das aufrufende Programm eine interaktive Bash-Sitzung ist). Und vielleicht möchten sie auch die Standardfehlerausgabe des aufgerufenen Programms ähnlich leiten ("jede Ausgabe dieses Befehls" könnte vernünftigerweise so interpretiert werden, dass auch stderr eingeschlossen ist).

2270voto

Zoredache Punkte 34350

Der Befehl, den Sie möchten, heißt tee:

foo | tee output.file

Zum Beispiel, wenn Sie nur an der Standardausgabe interessiert sind:

ls -a | tee output.file

Wenn Sie auch den Standardfehler einbeziehen möchten, tun Sie dies:

program [Argumente...] 2>&1 | tee outfile

2>&1 leitet Kanal 2 (stderr/Standardfehler) in Kanal 1 (stdout/Standardausgabe) um, sodass beides als stdout geschrieben wird. Es wird auch in die angegebene Ausgabedatei als Teil des tee Befehls geschrieben.

Zudem, wenn Sie an die Logdatei anhängen möchten, verwenden Sie tee -a wie folgt:

program [Argumente...] 2>&1 | tee -a outfile

193 Stimmen

Wenn OP möchte, dass "alle Ausgaben" umgeleitet werden, müssen Sie auch stderr abfangen: "ls -lR / 2>&1 | tee output.file"

49 Stimmen

@evanmcdonnal Die Antwort ist nicht falsch, sie ist möglicherweise einfach nicht spezifisch genug oder vollständig, abhängig von Ihren Anforderungen. Es gibt sicherlich Situationen, in denen Sie stderr nicht als Teil der Ausgabe möchten, die in einer Datei gespeichert wird. Als ich vor 5 Jahren geantwortet habe, habe ich angenommen, dass der OP nur stdout wollte, da er stdout im Betreff des Beitrags erwähnt hat.

3 Stimmen

Ah, tut mir leid, ich war vielleicht ein wenig verwirrt. Als ich es versucht habe, habe ich einfach keine Ausgabe erhalten, vielleicht ist alles nach stderr gegangen.

575voto

Matthew Alpert Punkte 5733
$ Programm [Argumente...] 2>&1 | tee Ausgabedatei

2>&1 leitet die stderr- und stdout-Streams um. tee Ausgabedatei nimmt den Stream, den es bekommt, und schreibt ihn auf den Bildschirm und in die Datei "Ausgabedatei".

Dies ist wahrscheinlich wonach die meisten Leute suchen. Die wahrscheinliche Situation ist, dass ein Programm oder Skript lange arbeitet und eine Menge Ausgaben erzeugt. Der Benutzer möchte es regelmäßig auf Fortschritt überprüfen, möchte die Ausgabe aber auch in eine Datei schreiben.

Das Problem (besonders wenn stdout- und stderr-Streams gemischt werden) besteht darin, dass man darauf angewiesen ist, dass die Streams vom Programm gespült werden. Wenn zum Beispiel alle Schreibvorgänge von stdout nicht gespült werden, alle Schreibvorgänge von stderr hingegen gespült werden, dann landen sie in umgekehrter zeitlicher Reihenfolge in der Ausgabedatei und auf dem Bildschirm.

Es ist auch schlecht, wenn das Programm nur alle paar Minuten 1 oder 2 Zeilen zur Fortschrittsanzeige ausgibt. In einem solchen Fall würde der Benutzer bei fehlender Spülung der Ausgabe des Programms über Stunden hinweg überhaupt keine Ausgabe auf dem Bildschirm sehen, da sie nicht durch das Rohr geleitet wird.

Update: Das Programm unbuffer, Teil des expect-Pakets, wird das Problem der Zwischenspeicherung lösen. Dadurch werden stdout und stderr sofort auf den Bildschirm und in die Datei geschrieben und halten sie synchron, wenn sie kombiniert und auf tee umgeleitet werden. z.B.:

$ unbuffer Programm [Argumente...] 2>&1 | tee Ausgabedatei

0 Stimmen

Eine Lösung gefunden: Link

8 Stimmen

Kennt jemand einen 'Unbuffer' für macOS?

9 Stimmen

Wenn Sie unbuffer nicht verwenden können, enthält GNU coreutils ein Tool namens stdbuff, das verwendet werden kann, um die Ausgabepufferung zu verhindern, wie folgt $ stdbuf -o 0 programm [argumente...] 2>&1 | tee ausgabedatei

179voto

tsenapathy Punkte 4916

Ein weiterer Weg, der für mich funktioniert, ist,

 |& tee  

wie im GNU Bash Handbuch gezeigt

Beispiel:

ls |& tee files.txt

Wenn ‘|&’ verwendet wird, wird die Standardfehlerausgabe von Befehl 1 zusätzlich zu seiner Standardausgabe über das Rohr mit der Standardeingabe von Befehl 2 verbunden; es ist eine Abkürzung für 2>&1 |. Diese implizite Umleitung des Standardfehlers zur Standardausgabe wird nach eventuellen Umleitungen ausgeführt, die durch den Befehl angegeben sind.

Für weitere Informationen, siehe Umleitungen

13 Stimmen

Wenn du danach $? verwendest, wird es den Statuscode von tee zurückgeben, was wahrscheinlich nicht das ist, was du willst. Stattdessen kannst du ${PIPESTATUS[0]} verwenden.

3 Stimmen

Dieser Methode verwirft farbige Konsolenausgabe, irgendwelche Ideen?

1 Stimmen

Versuchen Sie: unbuffer ls -l --color=auto | tee files.txt

26voto

O.Badr Punkte 2390

Sie können in erster Linie die Lösung von Zoredache verwenden, aber wenn Sie die Ausgabedatei nicht überschreiben möchten, sollten Sie tee mit der -a-Option wie folgt verwenden:

ls -lR / | tee -a output.file

18voto

nitinr708 Punkte 1335

Etwas hinzufügen ...

Das Paket unbuffer hat Unterstützungsprobleme mit einigen Paketen unter Fedora und Red Hat Unix-Versionen.

Die Probleme beiseite legen

Das hat bei mir funktioniert

bash myscript.sh 2>&1 | tee output.log

Danke ScDF & matthew eure Tipps haben mir viel Zeit gespart.

1 Stimmen

Dies scheint eine Duplikat zu sein

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X