time
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[edit]
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[edit]
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"
.
Enable comment auto-refresher