Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I would like to display the completion time of a script.

What I currently do is -

date  ## echo the date at start
# the script contents
date  ## echo the date at end

This just show's the time of start and end of the script. Would it be possible to display a fine grained output like processor time/ io time , etc?

share|improve this question
up vote 87 down vote accepted

just use time when you call the script.

time yourscript.sh
share|improve this answer
This outputs three times: real, user and sys. For the meanings of these, see here. – Garrett Jul 9 '15 at 1:56

Just call times without arguments upon exiting your script.

With ksh or zsh, you can also use time instead. With zsh, time will also give you the wall clock time in addition to the user and system CPU time.

To preserve the exit status of your script, you can make it:

ret=$?; times; exit "$ret"

Or you can also add a trap on EXIT:

trap times EXIT

That way, times will be called whenever the shell exits and the exit status will be preserved.

$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
shell  0.67s user 0.01s system 100% cpu 0.677 total
children  0.00s user 0.00s system 0% cpu 0.677 total

Also note that all of bash, ksh and zsh have a $SECONDS special variable that counts the number of seconds since the shell was started. In both zsh and ksh93, that variable can also be made floating point (with typeset -F SECONDS) to get more precision. This is only wall clock time, not CPU time.

share|improve this answer
That $SECONDS variable is very useful, thanks! – andybuckley Jun 18 '14 at 12:00

If time isn't an option,

start=`date +%s`
end=`date +%s`

share|improve this answer
Note that this only works if you don't need sub-second precision. For some uses that might be acceptable, for others not. For slightly better precision (you're still invoking date twice, for example, so you might at best get millisecond precision in practice, and probably less), try using date +%s.%N. (%N is nanoseconds since the whole second.) – Michael Kjörling Oct 19 '12 at 19:17
Good point. I thought of that just after leaving the keyboard but didn't come back. ^^ Also remember, OP, that "date" will itself add a few milliseconds to the run time. – Rob Bos Oct 20 '12 at 15:54
This is nice, but with the improvement from @MichaelKjörling I get the following error:bash: 1390472071.282341976: syntax error: invalid arithmetic operator (error token is ".282341976"), so maybe this needs more clarification. – Chris H Jan 23 '14 at 10:15
@ChrisH Oh. Good pointing it out; bash arithmetic expansion is integer-only. I see two obvious options; either ditch the period in the date format string (and treat the resultant value as nanoseconds since epoch), so use date +%s%N, or use something more capable like bc to calculate the actual runtime from the two values like jwchew suggests. Still, I feel this approach is a suboptimal way of doing it; time is considerably better if available, for reasons outlined above. – Michael Kjörling Jan 23 '14 at 13:29
Just install bc and then do this: runtime=$( echo "$end - $start" | bc -l ) – redolent Feb 11 '15 at 22:01

I'm a bit late to the bandwagon, but wanted to post my solution (for sub-second precision) in case others happen to stumble upon this thread through searching. The output is in format of days, hours, minutes, and finally seconds:

res1=$(date +%s.%N)

# do stuff in here

res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)

printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds

Hope someone out there finds this useful!

share|improve this answer
start=$(date +%s.%N)


end=$(date +%s.%N)    
runtime=$(python -c "print(${end} - ${start})")

echo "Runtime was $runtime"

Yes, this calls Python, but if you can live with that then this is quite a nice, terse solution.

share|improve this answer
Beware that running that python command in a subshell and reading its output will take several millions of nanoseconds on most current systems. Same for running date. – Stéphane Chazelas Nov 22 '14 at 10:58
"Several millions of nanoseconds" is several milliseconds. People timing bash scripts are usually not very concerned about that (unless they run several billions of scripts per megasecond). – Zilk Jan 1 at 3:34

Here's a variation of Alex's answer. I only care about minutes and seconds, but I also wanted it formatted differently. So I did this:

start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")
share|improve this answer
begin=$(date +"%s")


termin=$(date +"%s")
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
share|improve this answer
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -M shihcheng.guo@gmail.com
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
echo 1
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."
share|improve this answer
How is this really different from the other answers already given which use date before and after the script and output the difference between them? – Eric Renouf Jan 15 at 4:11

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.