Wie kann ich die Zeit- und Befehlsausgabe auf dieselbe Pipe umleiten?

24

Angenommen, ich habe eine Binärdatei aufgerufen foo.

Wenn ich die Ausgabe eines fooanderen Prozesses umleiten möchte bar, könnte ich schreiben ./foo | bar.

Auf der anderen Seite wollte , wenn ich timefoo, und leiten Sie die Ausgabe von timeI, schreiben kann time (./foo) | bar.

Meine Frage ist, wie kann ich die Ausgabe von timean das Ende der Ausgabe von kleben foound durch dieselbe Pipe leiten ?

Die folgende Lösung ist nicht das, wonach ich suche, da sie zwei separate Instanzen des Prozesses startet bar, während ich eine einzelne gemeinsame Pipe zu einer einzelnen Instanz von möchte bar.

time (./foo | bar)  | bar

Für alle, die neugierig sind, liegt der Grund dafür, dass sie nicht zwei Instanzen von starten möchten, bardarin, dass barsie ein Netzwerkclient sein können, und ich möchte, dass die Zeitinformationen als Teil derselben http POSTNachricht wie die Prozessausgabe an den Server gesendet werden.

merlin2011
quelle
hier geantwortet, etwas bessere antwort
JDS

Antworten:

29

Wenn ich verstehe, wonach du fragst, wird das reichen. Ich benutze die Befehle ls ~und teeals Stellvertreter für ./foound bar, aber die allgemeine Form dessen, was Sie wollen, ist die folgende:

$ ( time ./foo ) |& bar

HINWEIS: Die Ausgabe von timewird bereits am Ende einer Ausgabe von angehängt ./foo. Dies wird nur in STDERR durchgeführt. Um es durch die Pipe umzuleiten, müssen Sie STDERR mit STDOUT kombinieren. Sie können entweder |&oder verwenden, 2>&1um dies zu tun.

$ ( time ./foo ) |& bar

-or-

$ ( time ./foo ) 2>&1 | bar

Beispiel

$ ( time ls . ) |&  tee cmd.log
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s

Und hier ist der Inhalt der Datei, cmd.logdie von erstellt wurde tee.

$ more cmd.log 
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s
slm
quelle
Beachten Sie, dass diese Syntax für BASH nicht funktioniert.
Jvriesem
1
@jvriesem alle Beispiele sind aus bash
slm
9

timeSendet seine Ausgabe standardmäßig an stderr anstelle von stdout. Sie müssen nur das umleiten, wo Sie es wollen.

Sie sagen "Auf der anderen Seite, wenn ich timefoo und die Ausgabe von umleiten wolltetime könnte ich schreiben time (./foo) | bar." aber das ist eigentlich falsch. In diesem Fall wird die Zeitausgabe weiterhin auf Ihrer Konsole angezeigt, und nur stdout wird umgeleitet.

Sie können stderr gezielt umleiten mit:

(time foo) 2>&1 | bar

oder alle Rohre mit:

(time foo) |& bar

Die Klammern werden benötigt, damit dies korrekt funktioniert.

Randalieren
quelle
0

Ich habe festgestellt, dass dies unter Solaris funktioniert. (time ls) &> file

anisbet
quelle
1
Dies unterscheidet sich nicht von den vorhandenen Lösungen
roaima