In an earlier article we discussed how to time the execution of a command. We will take a bit further in this article and look at a clever way to get the execution time of shell scripts.
As a sysadmin, I am often writing scripts to perform different maintenance or to automate repetitive tasks. I tend to lean on bash scripts pretty heavily and have written scripts in the past that take hours to complete. Because of this, I like to print out the time it took to execute when the script exits. Bash provides the perfect builtin variable for this function.
Bash SECONDS Variable
The Bash shell (and others include zsh) comes with a builtin variable called SECONDS. The SECONDS variable holds the amount of seconds since a shell was opened. You can echo the variable to see how long that shell was open.
$ echo $SECONDS
562
Using SECONDS Variable in a Bash Script
When you launch a Bash script, it spawns a new shell instance and in turn starts a counter for that shell. This makes it easy to get the amount of seconds it takes a script to run. Simply use echo or printf to display the value of the SECONDS variable.
In the example above, we are using the echo command to print the amount of seconds like so:
echo "It took $SECONDS seconds for this script to execute."
Formatting SECONDS for a Clean Bash Script
If all your scripts run in under a minute or so a simple echo of the seconds looks fine. When you start running into several minutes or hours, a long string of seconds isn't the most friendly way to represent time. Here we will create a function that formats seconds into hours, minutes, and seconds for display.
Here is our format time function:
format_time() {
((h=${1}/3600))
((m=(${1}%3600)/60))
((s=${1}%60))
printf "%02d:%02d:%02d\n" $h $m $s
}
Now that we have the function, we just need to pass the SECONDS variable to it as an argument.
echo "Script completed in $(format_time $SECONDS)"
That's it, you will now know how long your script took to run.
Additional Suggestions
I like to use some color in my scripts. Using color is not only for improving the look of a script, it can also help identify failures (red), warnings (yellow), and successes (green). To learn how to add color to your scripts read "Using Color in the Output of Your Bash Scripts".
When I use the SECONDS variable to time the execution of my scripts, I like to use an exit trap to print the execution time and do any necessary cleanup. Read "Using Trap to Exit Scripts Cleanly" for more information.
If you are interested in the countdown timer I used in the examples above, read "How to Make a Countdown Timer in Bash" to learn how it's done. We demonstrate several different styles including one that uses tput to color the whole screen for maximum visibility.
Conclusion
While it is possible to simply use the time command before calling your bash script, it isn't always the best route. Here we learned how to use the SECONDS variable to get the execution time of a shell script. The advantage of this is that you can format it anyway you like and make it more in line with the look of your output. I have seen it used in some creative ways in the past.
I hope you enjoyed this short tutorial and remember to follow us on Twitter and Facebook.
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
3 Comments
Join Our Newsletter
Categories
- Bash Scripting (17)
- Basic Commands (50)
- Featured (7)
- Just for Fun (5)
- Linux Quick Tips (98)
- Linux Tutorials (65)
- Miscellaneous (15)
- Network Tools (6)
- Reviews (2)
- Security (32)
$1 missing!?!
format_time() {
((h=$1/3600))
((m=($1%3600)/60))
((s=$1%60))
printf "%02d:%02d:%02d\n" $h $m $s
}
Please clarify
Correct! I was getting "missing argument" errors without the "$1" in the h, m, s assignments. http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_11_01.html has some information about positional parameters in functions.
I used the format_time() function and compared it to the result of running:
time
The result of the $SECONDS variable is the same as the "real" time of the time command.
Very nice for performance testing!