Free tech support / small logo


How can I time portions of a Linux shell script?

Just picked up your book Wicked Cool Shell Scripts and already have one quick question: While working on the startup scripts, I would like to place log timers at certain portions of scripts. Is it possible to log point A at he beginning of a section, do the processing, log point B at the end of the section and then log B minus A so I know exactly how long a section took to process?


Dave's Answer:

On first glance, I thought that this would be a particularly tough challenge, with some sort of requirement to parse and translate date and time stamps, but then I realized that it's actually remarkably straightforward as long as you have a decent version of the date command on your system.

What you want to use is the "+%s" string format to the date command. If you have a good version of the command, it'll output the number of seconds since the Epoch as a numeric value:

$ date +%s
1157490628

Your resolution would be in seconds, but it should be quite easy to run this command just before and just after the block in question, the do a simple subtraction to figure out the elapsed time. Like this:

before="$(date +%s)"
long block of slow code
after="$(date +%s)"
elapsed_seconds="$(expr $after - $before)"
echo Elapsed time for code block: $elapsed_seconds

If you want to go from Epoch time to a more coherent date/time string, you can use the "-r" flag to date. You can figure out the "after" time, for example, this way:

echo Finished up at $(date -r $after)

But it turns out that you can also specify a format string to the date command even with the "-r" flag in use, so you could also get the HH:MM:SS value only of the difference between the two values like this:

echo Elapsed time: $(date -r $elapsed_seconds +%H:%M:%S)

Hope that helps you see a solution path for your script!









Subscribe!
Never miss another Q&A article! Click to subscribe: Add to Google Reader Add to My Yahoo! Subscribe in NewsGator RDF XML
Comments

Hi there.

Alternatively, most shells have a 'time' facility built-in. This works in bash; your milage may vary for other shells.

----------------------------------
#!/usr/bin/bash

{ time {
  # Your section 1 code goes here
} } 2> timing_section_1.txt

{ time {
  # Your section 2 code goes here
} } 2> timing_section_2.txt
----------------------------------

This will output real, user and cpu timing information into the text files specified.

(The slightly odd-looking code blocks are needed to appropriately redirect standard error to a file. See http://www.cs.tut.fi/~jarvi/tips/bash.html for an explanation.)

Hope this helps.

Regards,
NeilS.

Posted by: NeilS at September 13, 2006 8:27 AM

thanks a lot!! i just grabbed your code, plugged it into my script and now have a timer-based control over my child processes. very useful!

Posted by: vicki at September 10, 2007 5:55 PM

line:
echo Finished up at $(date -r $after)

should actually read:
echo Finished up at $(date -d $after)

-d displays the time given by input string.
-r displays the time given by reference "file".

Kept getting "file does not exist error", found out that the "-d" flag was causing error.

Thanks for the script... saved me a bit of sanity and time... and these days, we need all the sanity we can get.

b@

Posted by: b@ at July 14, 2008 10:57 AM

Hi iwant to set my server time automaticlly with conecting with ssh to another host ant get correct time and change my server time in crontb enviroment please help me thanks

Posted by: farid at July 21, 2008 12:27 AM

Had to adjust the last line to get this to work for me -- final script below:

#!/bin/bash
before=$(date +%s)
echo Started : $(date)
# commands to time go here
after=$(date +%s)
elapsed_seconds=$(expr $after - $before)
echo Ended : $(date)
echo Elapsed time : $(date -d "1970-01-01 $elapsed_seconds sec" +%H:%M:%S)

Posted by: pat at July 27, 2008 2:04 AM

Perfect!

I had a number of scripts that I wanted to track session time on, along with other time variations. I have been able to use all of the information provided here with success and "right-out-of-the-box".

Finally, I can call some of my scripts completed.

Thanks much!

Posted by: aitd at October 31, 2008 10:01 PM


I was unaware of the use of the date command figure elapsed time, but after looking at it I can see that it has a limitation that prevents my using it. As neat as it is, it only works for elapsed times of less than a day. There is no %DAYS option for elapsed days, if you need to monitor things that run that long (or can potentially run that long).

Luckily the shell date arithmetic is pretty simple. You don't even need 'bc'.

(( DIFF = NOW - START ))
(( DAYS = DIFF / 86400 ))
(( HOURS = DIFF % 86400 / 3600 ))
(( MIN = DIFF % 3600 / 60 ))
(( SEC = DIFF % 60 ))
ELAP=$(printf "%03d:%02d:%02d:%02d" $DAYS $HOURS $MIN $SEC)

The printf adds leading zeros so the columns don't float. Not as slick as 'date -d', but the code above works for about a year (which should cover anything in real life).

Posted by: Rich at June 12, 2009 12:04 PM

On some systems the folowing command, will give unwanted numbers in the hour column (below)

$ echo $(date -r 110 +%H:%M:%S)
19:01:50

This is because you're reporting elapsed time since the epoch, but if you're not on GMT, then the epoch won't start at 00:00:00. (On EDT you get 19:00:00 for 0). Therefore you need to report in UTC as follows:

$ echo $(date -u -r 110 +%H:%M:%S)
00:01:50


Posted by: Cris at May 6, 2010 12:09 PM

Very Nice!
exactly what I was looking for.
thanks.

Posted by: blackarrow at September 29, 2010 3:32 PM

Thanks Dave - exactly what I needed!

Posted by: PeteW at July 29, 2011 8:48 AM

I have something to say, now that you mention it, but ...
Starbucks coffee cup I do have a lot to say, and questions of my own for that matter, but first I'd like to say thank you for all your efforts on this Web site by buying you a cup of coffee!

I do have a comment, now that you mention it!











Remember personal info?


Please note that I will never send you any unsolicited email. Ever.

While I'm at it, please note that by submitting a question or comment you're agreeing to my terms of service, which are: you relinquish any subsequent rights of ownership to your material by submitting it on this site.









Recent Entries


Search
I Need Help!
Need Help? Ask Dave Taylor!


© 2002 - 2012 by Dave Taylor. All Rights Reserved.

Note: This web site is for the purpose of disseminating information for educational purposes, free of charge, for the benefit of all visitors. We take great care to provide quality information. However, we do not guarantee, and accept no legal liability whatsoever arising from or connected to, the accuracy, reliability, currency or completeness of any material contained on this web site or on any linked site.

[whiteboard marker tray]
"Ask Dave Taylor®" is a registered trademark of Intuitive Systems, LLC.