Come posso reindirizzare l'output `time` e comandare l'output sulla stessa pipe?


24

Supponiamo che io abbia un binario chiamato foo.

Se voglio reindirizzare l'output di fooun altro processo bar, potrei scrivere ./foo | bar.

D'altra parte, se volevo timefoo, e reindirizzare l'output del timePotrei scrivere, time (./foo) | bar.

La mia domanda è: come posso attaccare l'output di timealla fine dell'output fooe instradarlo attraverso lo stesso pipe ?

La seguente soluzione non è quella che sto cercando, perché avvia due istanze separate del processo bar, mentre voglio una singola pipe condivisa, in una singola istanza di bar.

time (./foo | bar)  | bar

Per chiunque sia curioso, la ragione per non voler avviare due istanze di barè perché barpuò essere un client di rete e voglio che le informazioni di temporizzazione vengano inviate al server come parte dello stesso http POSTmessaggio dell'output del processo.


risposto qui, risposta un po 'migliore: stackoverflow.com/questions/13356628/…
JDS

Risposte:


29

Se capisco cosa mi stai chiedendo, lo farò. Sto usando i comandi ls ~e teegli stand-in per ./fooe bar, ma la forma generale di ciò che vuoi è questa:

$ ( time ./foo ) |& bar

NOTA: l'output di timeè già stato collegato alla fine di qualsiasi output da ./foo, è appena stato fatto su STDERR. Per reindirizzarlo attraverso il tubo è necessario combinare STDERR con STDOUT. Puoi usare |&o 2>&1per farlo.

$ ( time ./foo ) |& bar

-or-

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

Esempio

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

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

Ed ecco il contenuto del file cmd.logprodotto da tee.

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

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

Nota che questa sintassi non funziona per BASH.
jvriesem,

1
@jvriesem tutti gli esempi provengono da bash
slm

9

timeinvia il suo output a stderr invece di stdout per impostazione predefinita. Hai solo bisogno di reindirizzare quello dove lo vuoi.

Dici "D'altra parte, se volessi timecercare, e reindirizzare l'output di timepotrei scrivere, time (./foo) | bar". ma questo non è corretto. In questo caso, l'output del tempo verrà comunque visualizzato sulla console, verrà reindirizzato solo lo stdout.

Puoi reindirizzare stderr specificatamente con:

(time foo) 2>&1 | bar

o tutti i tubi con:

(time foo) |& bar

Le parentesi sono necessarie affinché questo funzioni correttamente.


0

Ho scoperto che questo funziona su Solaris. (time ls) &> file


1
Questo non è diverso da nessuna delle soluzioni esistenti
roaima il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.