3

Usually, the time command outputs three lines:

> time sleep 2
real    0m2.003s
user    0m0.000s
sys     0m0.006s

However, when prepended with variable assignment, the output becomes one line:

> VAR="" time sleep 2
0.00user 0.00system 0:02.00elapsed 0%CPU (0avgtext+0avgdata 2060maxresident)k
0inputs+0outputs (0major+86minor)pagefaults 0swaps

Why is this happening? And is there a way to keep variable assignment while having the output in three lines?

justhalf
  • 183

2 Answers2

5

Why is this happening?

In Bash time is a reserved word (keyword) that can precede and measure not only a simple command; it can measure a pipeline. As such, it must be the first word. This syntax only informs Bash that you want to measure time; the rest of the pipeline is still processed by Bash as if time wasn't there.

If time is not the first word and still can be interpreted as a command, it's interpreted as a regular external command (not even a builtin), looked up in $PATH and executed; e.g. it can be /usr/bin/time. This tool processes its arguments and builds the actual command from them.

The two utilities produce output in different formats.


And is there a way to keep variable assignment while having the output in three lines?

Yes. You can use time as the first word, so it gets interpreted as the keyword:

time VAR="" sleep 2

Note both implementations support -p that changes the output format to that specified by POSIX (in fact the support for -p itself is required by POSIX). This means the following two commands will produce output in the same format:

time -p VAR="" sleep 2
VAR="" time -p sleep 2

Under the hood, however, these are very different.

0

Time sends its output to STDERR and not STDOUT.

There are a couple of options though I'm not clear on how you plan to use the captured data so I'll lay it out in three lines.

$ narf="$( ( time sleep 2 ) 2>&1 )" ; echo "${narf}" ; unset narf  

real    0m2.002s
user    0m0.001s
sys 0m0.001s

$ narf="$( ( time sleep 5 ) 2>&1 )" ; echo "${narf}" ; unset narf  

real    0m5.002s
user    0m0.001s
sys 0m0.001s

$ narf="$( ( time -p sleep 5 ) 2>&1 )" ; echo "${narf}" ; unset narf  
real 5.00
user 0.00
sys 0.00

The first two options do not use the -p formatting option (which is designed for POSIX compliance). The third option does.

As you can see the output varies somewhat. Ask me questions if you'd like. (You can drop the unset command as I was using that to perform multiple tests.)

JamesIsIn
  • 191