64

How would you find out how long a running process took to complete?

Example:

 date; dd bs=1m if=/foo of=bar; date

^This example only has 1 second of resolution.

Any shell is acceptable.

spuder
  • 17,643
  • 36
  • 91
  • 119

1 Answers1

111

use time:

$ time somecommand --argument=ofsomecommand

time will execute the rest of the command line as a command (in this example somecommand --argument=ofsomecommand) and when the command is done it will print the elapsed time.

example output (if you are using bash):

$ time somecommand --argument=ofsomecommand
...
... (output of somecommand)
...
real    0m5,020s
user    0m0,010s
sys     0m0,010s

the information that you typically want is this line: real 0m5,020s. that means the command took about 5 seconds. for more information about the other numbers see here: https://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1


time is a builtin command in most shells. the example output above is from the bash builtin. sometimes you will want to use the "system" time. the (directly visible) difference is the different output format. but there are more implications of the shell builtin time vs. system time which is not discussed further here.

if you want to use the system time you have, among other, following options:

$ /usr/bin/time somecommand --what=islove

or

$ command time somecommand --what=isyourquest

there are more but that is outside the scope of this question and answer.

the command method works in bash and maybe some other shells. but might have different behaviour if used in scripts or functions or subshells or whatnot.

invoking the binary directly /usr/bin/time is probably the most safe and portable method to avoid the shell builtin time.

for more information on the difference of a shell builtin and a system command read here: What is the difference between a builtin command and one that is not?


example output using system time:

$ /usr/bin/time somecommand --what=argument
...
... (output of somecommand)
...
0.00user 0.01system 0:06.02elapsed 0%CPU (0avgtext+0avgdata 3656maxresident)k
0inputs+0outputs (0major+1089minor)pagefaults 0swaps

the information that you typically want is 0:06.02elapsed. that means the command took about 6 seconds. for the meaning of the other numbers read the man page: http://man7.org/linux/man-pages/man1/time.1.html

you can change the output of the system time. use -p to get output similar to the shell builtin time:

$ /usr/bin/time -p sleep 1.5
real 1.50
user 0.00
sys 0.00

use -f to write your own format:

$ /usr/bin/time -f %E sleep 1.5
0:01.50

%E is the "elapsed" part. the part you are usually most interested in.


how to redirect or capture the output

for demonstration observe command hellostdoutstderr:

#!/bin/sh
sleep 0.5
echo stdout
echo stderr >&2

example invocations:

 $ ./hellostdoutstderr 
stdout
stderr

capture stdout and stderr separately

$ ./hellostdoutstderr >stdout 2>stderr
$ cat stdout
stdout
$ cat stderr
stderr

the system time prints to stderr so it is captured in the stderr redirect

$ /usr/bin/time ./hellostdoutstderr >stdout 2>stderr
$ cat stdout
stdout
$ cat stderr
stderr
0.00user 0.00system 0:00.50elapsed 1%CPU (0avgtext+0avgdata 3672maxresident)k
0inputs+16outputs (0major+311minor)pagefaults 0swaps

you can tell the system time to print to a separate file

$ /usr/bin/time -o timeout ./hellostdoutstderr >stdout 2>stderr
$ cat stdout
stdout
$ cat stderr
stderr
$ cat timeout 
0.00user 0.00system 0:00.50elapsed 1%CPU (0avgtext+0avgdata 3676maxresident)k
0inputs+16outputs (0major+309minor)pagefaults 0swaps

the bash builtin time always prints to the terminal even if stdout and stderr is redirected. this is possible because it is a builtin and can do whatever it likes (in the shell)

$ time ./hellostdoutstderr >stdout 2>stderr

real    0m0,511s
user    0m0,005s
sys 0m0,006s

stdout and stderr are captured but bash builtin time still prints to shell. it is possible to capture the output of the bash builtin time but why fight bash if it is easier to use system time (/usr/bin/time).


to time more complex commands you have severals options

if you just want to time two command one after the other

$ time { command1 ; command2 ; }

also works with pipe

$ time { command1 | command2 ; }

for more complex stuff

$ time sh -c ' complex command chain '

but mind the quoting and other shenanigans. better put the commands in a script and time the script:

$ time ./script.sh
Lesmana
  • 26,889
  • 20
  • 81
  • 86
  • 2
    Note that \ is a shortcut version of the `command` function of bash, so `command time longrunningcommand --pedantic-comments` is the same :) – Drav Sloan Aug 13 '13 at 22:24
  • 2
    Additionally you can do `time { command; command2; }` – sparticvs Aug 14 '13 at 00:33
  • 2
    I dont get it, what are the comments for? what is the output of this function? – j0h Apr 05 '16 at 14:58
  • I'm with @j0h -- how do you actually use this? You've shown how to invoke it, but not how to acquire the result. (Experimentally, I've determined that the result is printed to stdout _if_ the command has no output of its own, but what if it does?) And what are the meanings of `--getsomecoffee` and `--callmom`? Does this somehow label the thing being timed? This answer needs improvement. (And yes, I'm aware two years have gone by.) – JakeRobb Apr 23 '18 at 19:32
  • 1
    i elaborated the answer. now give me upvotes. sweet sweet upvotes. – Lesmana Apr 24 '18 at 17:10
  • Is it possible to execute time-command with every command I type – Love Grover May 09 '21 at 12:23