Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
add comment

2 Answers

up vote 11 down vote accepted

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
share|improve this answer
add comment

time sends its output to stderr instead of stdout by default. You just need to redirect that where you want it.

You say "On the other hand, if I wanted to time foo, and redirect the output of time I could write, time (./foo) | bar." but this is actually incorrect. In this case, the output of time would still be displayed on your console, only stdout would be redirected.

You can redirect stderr specifically with:

(time foo) 2>&1 | bar

or all pipes with:

(time foo) |& bar

The brackets are needed for this to work correctly.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.