time

From LinuxReviews
Jump to navigationJump to search
Konsole.svg

time is actually two (or more) commands on most GNU/Linux distributions. One is the shells built-in time command and the other is GNU time which can be executed using it's full path. time is useful for measuring how long it takes to complete a process and how much of that is real, user and system utilization time.

Using Shell Built-In "time" In Scripts

One major problem with the bash builtin time command is that it redirects output to the terminal almost regardless of how you try to run it:

$ time echo "hi" > log.txt

real	0m0.003s
user	0m0.000s
sys 	0m0.000s

One solution is to wrap time and the command you wish to run in a sub-shell:

$ { time echo "hi" ; } 2>> log.txt
hi
$ cat log.txt 

real	0m0.000s
user	0m0.000s
sys 	0m0.000s
$

The command inside the brackets must be terminated with a ;.

{ time echo "hi" } 2>> log.txt

...will not work because of the missing ;. This will work:

{ time echo "hi" ; } 2>> log.txt

Put a redirect inside the brackets if you want the standard error output (STDERR) from the command logged to one file and time's output to another:

{ time echo "hi" 2> such_errors.txt ; } 2>> log.txt

places any errors from echo "hi" in such_errors.txt and the time it takes to run that command in log.txt.

You need to redirect STDERR (2) to STDOUT (1) if you want to pipe (|) the time output to another program and use or manipulate it:

{ time echo "hi"; } 2>&1 | grep real

You can redirect the output from time to a file without interfering with either STDIN or STDERR by sending time's STDERR to file descriptor 3 and then send it back:

{ time { echo "hi" 2>&3; }; } 3>&2 2>> log.txt

The last example is useful if you want to do something like waifu2x benchmarking and you want the time in a log but you do want the output and any errors in a terminal:

#!/bin/sh
function runbenchmark(){
  for f in anime-girls-with-questionmarks/*.jpg;do
    outputf="output${1}/${f/anime-girls-with-questionmarks\//}"
    $HOME/bin/waifu2x-ncnn-vulkan \
      -m $HOME/bin/waifu2x-ncnn/models-cunet \
      -g ${1} -i $f -o $outputf 2>/dev/null
  done
  rm output/*.jpg
}

for GPU in 0 1;do
  sync
  echo '#####################################################' >> waifu2x-ncnn-log.txt
  vulkaninfo 2>/dev/null |grep "GPU id = ${GPU}"|head -n 1 >> waifu2x-ncnn-log.txt
  { time { runbenchmark ${GPU} 2>&3; }; } 3>&2 2>> waifu2x-ncnn-log.txt
done

Enter GNU time

One big confuse when it comes to time is that shells like Bash have their own built-in time command which takes precedence over the GNU time binary that is typically installed as /usr/bin/time. If you look at the time.1 manual page you'll find options that don't work and don't apply if you simply run time since what you use in that case is the shell's time command, not the time binary with GNU time.

You need to either prefix time with a \ or use the full path to use the GNU time:

$ \time echo "hi"
hi
0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 2004maxresident)k
64inputs+0outputs (2major+103minor)pagefaults 0swaps

Note that it doesn't matter if you type \time or the full /usr/bin/time path, both make the shell realize that the built-in time command should not be used.

It too outputs as STDERR, not STDOUT:

\time 2> log.txt echo "hi"

The above command places time's output in log.txt.

GNU time has two options that eliminates the need to pipe it's output.

-o file.txt Places time's output in file.txt, overwriting file.txt
-a Appends to the output file when it is combined with -o
/usr/bin/time -o log.txt echo "hi"

accomplishes the same as /usr/bin/time 2> log.txt echo "hi".

Add your comment
LinuxReviews welcomes all comments. If you do not want to be anonymous, register or log in. It is free.