How to use a timer in bash?

I needed a timer which will start at the very beginning of the script and stops at the end.

Asked By: N. F.

||

You could use Linux’s built-in time command. From the man page:

time COMMAND [arguments]

time determines which information to display about the resources used by the COMMAND from the string FORMAT. If no format is specified on the command line, but the TIME environment variable is set, its value is used as the format.

To time the cleanup.sh script, use:

$ time cleanup.sh
Answered By: Marius Cotofana

If you want the duration in seconds, at the top use

start=$SECONDS

and at the end

duration=$(( SECONDS - start ))
Answered By: glenn jackman

I realise this is a pretty old question but this is the way I do it for anything when I want/need to know how long something took to run.

Bash has a built-in seconds timer in the form of an internal variable named SECONDS(see: here for other internal variables)

Put SECONDS=0 before whatever you’re checking the run time of. It needs to be after any user input to get a good result so if you’re prompting for information, put it after the prompt(s).

Then, put this at the end of what you’re checking:

if (( $SECONDS > 3600 )) ; then
    let "hours=SECONDS/3600"
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $hours hour(s), $minutes minute(s) and $seconds second(s)" 
elif (( $SECONDS > 60 )) ; then
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $minutes minute(s) and $seconds second(s)"
else
    echo "Completed in $SECONDS seconds"
fi

If you only want to know the time in seconds, you can simplify the above to:

echo "Completed in $SECONDS seconds"

As an example:

read -rp "What's your name? " "name"
SECONDS=0
echo "Hello, $name"
if (( $SECONDS > 3600 )) ; then
    let "hours=SECONDS/3600"
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $hours hour(s), $minutes minute(s) and $seconds second(s)" 
elif (( $SECONDS > 60 )) ; then
    let "minutes=(SECONDS%3600)/60"
    let "seconds=(SECONDS%3600)%60"
    echo "Completed in $minutes minute(s) and $seconds second(s)"
else
    echo "Completed in $SECONDS seconds"
fi
Answered By: Philip Gibbons
#!/bin/bash

start=$(date +%s)
#
# do something
sleep 10
#
#
end=$(date +%s)

seconds=$(echo "$end - $start" | bc)
echo $seconds' sec'

echo 'Formatted:'
awk -v t=$seconds 'BEGIN{t=int(t*1000); printf "%d:%02d:%02dn", t/3600000, t/60000%60, t/1000%60}'
Answered By: anask

@anask do a clever solution for this answer, just I recommend to use the native $SECONDS instead to create a new one

awk -v t=$SECONDS 'BEGIN{t=int(t*1000); printf "Elapsed Time (HH:MM:SS): %d:%02d:%02dn", t/3600000, t/60000%60, t/1000%60}'

The purpose of the printf and the division is to convert the elapsed seconds to the corresponded unity Hours, Mins, Secs, respective.

Answered By: Alex Galindo

I’ve recently been attempting something similar. I would suggest:

date1=$(date +%s)

#Use this arithmetic to determine elapsed time since defining date1
$(( $(date +%s) - $date1 ))

#While loop using timer
while ! [ $(( $(date +%s) - $date1 )) -gt 10 ]; do
    #Terminal timer -n won't append new line, so the echo will replace itself. 
    ##There is also some date formatting to achieve: HH:MM:SS.
    echo -ne "$(date -u --date @$(( $(date +%s) - $date1 )) +%H:%M:%S)r"
done
Answered By: MickyG
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.