Wie kann man stderr und stdout in verschiedene Dateien umleiten und auch im Terminal anzeigen?

30

Ich möchte die Ausgabe eines Befehls im Terminal sehen, als gäbe es keine Umleitung. Außerdem muss stderr zu err.log und stdout zu stdout.log umgeleitet werden.

Es wäre schön, wenn Sie auch die exakte Kopie dessen, was im Terminal angezeigt wird, dh Fehler, die gedruckt werden, wenn sie auftreten, in einer separaten Datei haben würden: stdouterr.log.

balki
quelle
@Nuno Nein, ist es nicht. Das OP möchte unterschiedliche Dateien für stdout und stderr haben.
Dogbane
@dogbane Ja, du hast recht. Das tut mir leid.
Nuno C. Inácio
Ich finde diese Frage immer noch sehr vertraut. Lassen Sie mich nachschlagen ... Hier ist eine sehr ähnliche unix.stackexchange.com/q/4195/250 , und hier ist eine verwandte unix.stackexchange.com/q/1416/250
phunehehe 25.01.11

Antworten:

37

Verwenden Sie den teeBefehl wie folgt:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 So tauschen Sie stderr und stdout aus, weil tee nur stdout akzeptieren kann.

Werfen Sie einen Blick auf den Unix-Befehl tee, um erweiterte Umleitungen mit zu erhalten tee.

Dogbane
quelle
schöne lösung. Gibt es eine Möglichkeit, Cmd-Exit-Code zu erhalten?
Turbanoff
2
@turbanoff Ersetzen cmddurch (cmd ; echo >exit_code.txt $?).
Parthian Shot
Ich glaube, dies sollte die Reihenfolge der Ausgabe auf der Kommandozeile besser bewahren:((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log)
TTT
5

Ich halte es für eine großartige Idee, stdout und stderr in zwei verschiedenen Dateien zu protokollieren. Werden die Protokolle nicht asynchron? Also habe ich folgendes ausprobiert:

  • stdout to "stdout.log" (wie dogbane vorschlug)
  • stderror to "stderr.log" (wie dogbane vorschlug)
  • Alle Ausgaben in "all.log" und
  • kann die Ausgabe weiterhin auf dem Display sehen (allerdings in einem separaten Terminal!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

in einem anderen Terminal

tail -f --sleep-interval=2 all.log
Sreeni
quelle
Ist es nicht möglich, stderr direkt auf ein zweites tty zu lenken? Dann ist keine Protokolldatei erforderlich.
Steven Lu
@StevenLu Ja, wenn Sie den Namen kennen und die Berechtigung haben, auf die zweite Tty zu schreiben, die ausgeführt werden kann.
Jasen
1
einfacher wäre &| tee all.logam Ende des Befehls statt&> all.log
Jasen
@Jasen: 2. Mal sehe ich &|. Ich verstehe &>, |&auch, aber was bedeutet &|in diesem Zusammenhang? Ich konnte keine passende Syntaxreferenz finden, nicht im
Internet
1
@Cbhihe, soweit ich das beurteilen kann, macht es nichts, ich wollte sagen|&
Jasen
3

@dogbane, Danke.
Ich habe auch einen anderen Weg gefunden, bei dem beide Streams ungefähr in der Reihenfolge gespeichert werden, in der sie ohne Umleitung gedruckt würden.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

Dies funktioniert jedoch nur mit den Shells, die die Prozessersetzung unterstützen.

balki
quelle
-2

Versuche dies :

command 2>&1 | tee bothLog
vasile
quelle
4
Hallo Vasile, das beantwortet nicht die Frage: balki benötigt separate Dateien für stdout und stderr, deine Lösung würde beides im selben Stream mischen.
Mat
Warum verschmelzen Leute stdout und stderr miteinander? Oder andere dazu auffordern?
Nurettin