Last updated on March 9, 2021 by Dan Nanni
Elapsed time is the amount of wall-clock time that has passed between the beginning and the end of a particular event. In other words, elapsed time is a measurement of actual time taken for the event to complete. It is common to to measure elapsed time as part of application performance analysis and profiling. While you are working on a bash script, you may also want to add instrumentation in your script to calculate elapsed time for various components (e.g., a bash function, an external command, etc). In this tutorial, let's find out how to measure elapsed time in a bash script.
The most common way to measure elapsed time in bash is to utilize the
date command, which can show the current system date and time in a configurable format. Using the flexiblity of
date's display format, you can easily calculate elapsed time with different resolutions.
When you call
+%s option, it shows the current system clock in seconds since 1970-01-01 00:00:00 UTC. Thus, with this option, you can easily calculate time difference in seconds between two clock measurements.
start_time=$(date +%s) # perform a task end_time=$(date +%s) # elapsed time with second resolution elapsed=$(( end_time - start_time ))
Another (preferred) way to measure elapsed time in seconds in bash is to use a built-in bash variable called
SECONDS. When you access
SECONDS variable in a bash shell, it returns the number of seconds that have passed so far since the current shell was launched. Since this method does not require running the external
date command in a subshell, it is a more elegant solution.
start_time=$SECONDS sleep 5 elapsed=$(( SECONDS - start_time )) echo $elapsed
This will display elapsed time in terms of the number of seconds. If you want a more human-readable format, you can convert
$elapsed output as follows.
eval "echo Elapsed time: $(date -ud "@$elapsed" +'$((%s/3600/24)) days %H hr %M min %S sec')"
This will produce output like the following.
Elapsed time: 0 days 13 hr 53 min 20 sec
To measure elapsed time with millisecond resolution, use
+%s.%3N option, which returns the current time in milliseconds. Since bash does not support floating point arithmetic, you need to rely on an external calculator tool such as
bc to compute time difference with millisecond resolution. The
bc calculator allows you to specify the precision of floating point numbers (i.e., number of digits after floating point) with
scale variable. Thus, with
bc computes time difference with millisecond resolution.
start_time=$(date +%s.%3N) # perform a task end_time=$(date +%s.%3N) # elapsed time with millisecond resolution # keep three digits after floating point. elapsed=$(echo "scale=3; $end_time - $start_time" | bc)
Technically it is possible to calculate elpased time with a higher resolution such as microsecond-level or nanosecond-level using
date command, since
date can show current time in nanosecond resolution. However, such high-resolution elapsed time measurements with
date command will not be anywhere near accurate due to the variable cost of invoking the external
date command in a subshell.
As a simple illustration, let's run the following bash script to measure elapsed time of noop (i.e., do nothing) with microsecond resolution.
while : ; do start_time=$(date +%s.%6N) : # do nothing end_time=$(date +%s.%6N) elapsed=$(echo "scale=6; $end_time - $start_time" | bc) echo $elapsed done
.002829 .002890 .002664 .002456 .002395 .002451 .002397 .002401 .002373 .002449 .002457 .002475 .002753 .002357 .002420 .002442 .002451 .002449
As you can see above, elapsed time for the same operation (i.e., do nothing) does not remain constant on microsecond-level. This proves that any sub-milliseond-level elapsed time measurement based on an external command will be highly misleading.
If you know of any trick that can improve the accuracy of elapsed time measurement in bash, feel free to share it in the comment.
bashshell scripting tutorials provided by Xmodulo.
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.