How can I redirect `time` output and command output to the same pipe?
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
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.