Get program execution time in the shell
I want to execute something in a linux shell under a few different conditions, and be able to output the execution time of each execution. I know I could write a perl or python script that would do this, but is there a way I can do it in the shell? (which happens to be bash)
11 Answers 11
Use the built-in time keyword:
$ help time time: time [-p] PIPELINE Execute PIPELINE and print a summary of the real time, user CPU time, and system CPU time spent executing PIPELINE when it terminates. The return status is the return status of PIPELINE. The `-p' option prints the timing summary in a slightly different format. This uses the value of the TIMEFORMAT variable as the output format.
real 0m2.009s user 0m0.000s sys 0m0.004s
How is this used on a command like time -p i=x; while read line; do x=x; done < /path/to/file.txt ? It immediatly returns 0.00 unless I don't put anything before the while loop.. what gives?
@natli: While time can time an entire pipeline as-is (by virtue of being a Bash keyword), you need to use a group command ( < . ; . ; >) to time multiple commands: time -p < i=x; while read line; do x=x; done < /path/to/file.txt; >
You can get much more detailed information than the bash built-in time (i.e time(1), which Robert Gamble mentions). Normally this is /usr/bin/time .
Editor’s note: To ensure that you’re invoking the external utility time rather than your shell’s time keyword, invoke it as /usr/bin/time . time is a POSIX-mandated utility, but the only option it is required to support is -p . Specific platforms implement specific, nonstandard extensions: -v works with GNU‘s time utility, as demonstrated below (the question is tagged linux); the BSD/macOS implementation uses -l to produce similar output — see man 1 time .
Example of verbose output:
$ /usr/bin/time -v sleep 1 Command being timed: "sleep 1" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 1% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 0 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 210 Voluntary context switches: 2 Involuntary context switches: 1 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
How can I measure the execution time of a terminal process?
I’m trying to measure the execution time of a process that I call via the command line (i.e., I want to find out how long it takes to for the process to finish). Is there any command that I can add to the command calling the process that will achieve this?
8 Answers 8
Add time before the command you want to measure. For example: time ls .
The output will look like:
real 0m0.606s user 0m0.000s sys 0m0.002s
Explanation on real , user and sys (from man time ):
- real : Elapsed real (wall clock) time used by the process, in seconds.
- user : Total number of CPU-seconds that the process used directly (in user mode), in seconds.
- sys : Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds.
@ninjalj, can you provide more information on what the real , user , and sys times are that this command returns?
Note that you may need sudo apt-get install time if you are using a shell where time is not a builtin.
Note that this is the output from Bash’s time builtin, but man time would be about an executable (like /usr/bin/time , from the time package), and its output would look different. Also in Bash, you can run help time for help with the builtin.
Note that the process end does not mean all the work is finished. A copy may take additional minutes after the «time» returns for flushing system bufffers (therefor with unallocated sys time also).
For a line-by-line delta measurement, try gnomon.
It is a command line utility, a bit like moreutils’s ts, to prepend timestamp information to the standard output of another command. Useful for long-running processes where you’d like a historical record of what’s taking so long.
Piping anything to gnomon will prepend a timestamp to each line, indicating how long that line was the last line in the buffer—that is, how long it took the next line to appear. By default, gnomon will display the seconds elapsed between each line, but that is configurable.
Is there a way to find the running time of the last executed command in the shell?
Is there a command like time that can display the running time details of the last or past executed commands on the shell?
7 Answers 7
zsh has some built in features to time how long commands take.
If you enable the inc_append_history_time option with
Then the time taken to run every command is saved in your history and then can be viewed with history -D .
I do not know, how it is in bash, but in zsh you can define preexec and precmd functions so that they save the current time to variables $STARTTIME (preexec) and $ENDTIME (precmd) so you will be able to find the approximate running time. Or you can define an accept-line function so that it will prepend time before each command.
UPDATE: This is the code, which will store elapsed times in the $_elapsed array:
preexec () < (( $#_elapsed >1000 )) && set -A _elapsed $_elapsed[-1000,-1] typeset -ig _start=SECONDS > precmd()
Then if you run sleep 10s :
% set -A _elapsed # Clear the times % sleep 10s % sleep 2s ; echo $_elapsed[-1] 10 % echo $_elapsed 0 10 0
No need in four variables. No problems with names or additional delays. Just note that $_elapsed array may grow very big, so you need to delete the first items (this is done with the following piece of code: (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1] ).
UPDATE2: Found the script to support zsh-style precmd and preexec in bash. Maybe you will need to remove typeset -ig (I used just to force $_start to be integer) and replace set -A var . with var=( . ) in order to get this working. And I do not know how to slice arrays and get their length in bash.
UPDATE3: Found one problem: if you hit return with an empty line preexec does not run, while precmd does, so you will get meaningless values in $_elapsed array. In order to fix this replace the precmd function with the following code:
precmd () < (( _start >= 0 )) && set -A _elapsed $_elapsed $(( SECONDS-_start )) _start=-1 >
How to check how long a process has been running?
On Linux with the ps from procps(-ng) (and most other systems since this is specified by POSIX):
Where $$ is the PID of the process you want to check. This will return the elapsed time in the format [[dd-]hh:]mm:ss .
Using -o etime tells ps that you just want the elapsed time field, and the = at the end of that suppresses the header (without, you get a line which says ELAPSED and then the time on the next line; with, you get just one line with the time).
Or, with newer versions of the procps-ng tool suite (3.3.0 or above) on Linux or on FreeBSD 9.0 or above (and possibly others), use:
(with an added s ) to get time formatted just as seconds, which is more useful in scripts.
On Linux, the ps program gets this from /proc/$$/stat , where one of the fields (see man proc ) is process start time. This is, unfortunately, specified to be the time in jiffies (an arbitrary time counter used in the Linux kernel) since the system boot. So you have to determine the time at which the system booted (from /proc/stat ), the number of jiffies per second on this system, and then do the math to get the elapsed time in a useful format.
It turns out to be ridiculously complicated to find the value of HZ (that is, jiffies per second). From comments in sysinfo.c in the procps package, one can A) include the kernel header file and recompile if a different kernel is used, B) use the posix sysconf() function, which, sadly, uses a hard-coded value compiled into the C library, or C) ask the kernel, but there’s no official interface to doing that. So, the ps code includes a series of kludges by which it determines the correct value. Wow.
So it’s convenient that ps does that all for you. 🙂