Shell – Redirect `time` Output and Command Output to the Same Pipe

command linepipeshelltime-utility

Suppose I have a binary called foo.

If I want to redirect the output of foo to some other process bar, I could write ./foo | bar.

On the other hand, if I wanted to time foo, and redirect the output of time I could write, time (./foo) | bar.

My question is, how can I stick the output of time to the end of the output of foo and pipe it through the same pipe?

The following solution is not what I am looking for, because it starts two separate instances of the process bar, while I want a single shared pipe, to a single instance of bar.

time (./foo | bar)  | bar

For anyone who is curious, the reason for not wanting to start two instances of bar is because bar can be a network client and I want the timing information to be sent to the server as part of the same http POST message as the process output.

Best Answer

If I understand what you're asking for I this will do. I'm using the commands ls ~ and tee as stand-ins for ./foo and bar, but the general form of what you want is this:

$ ( time ./foo ) |& bar

NOTE: The output of time is already being attached at the end of any output from ./foo, it's just being done so on STDERR. To redirect it through the pipe you need to combine STDERR with STDOUT. You can use either |& or 2>&1 to do so.

$ ( time ./foo ) |& bar

-or-

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

Example

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

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

And here's the contents of the file cmd.log produced by tee.

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

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