40

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

3
42

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

start=$SECONDS

and at the end

duration=$(( SECONDS - start ))
2
31

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
1
15

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
2
  • 3
    A shortcut for those who don't want such an elaborate time formatting: date +%T -d "1/1 + $SECONDS sec" (limited to less than 24h, but you can adapt to add days too)
    – xhienne
    Mar 29 '17 at 0:40
  • Excellent link to TLDP's Internal Variables. Thank you for that! Dec 9 '19 at 16:02
5
#!/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:%02d\n", t/3600000, t/60000%60, t/1000%60}'
2
  • 1
    Hi, welcome on the Unix SE! Code-only answers don't look very well, maybe you could explain what your script is doing.
    – peterh
    Jun 14 '18 at 21:44
  • Why do you multiply by 1000 here and then divide by 1000*modifier later for all of the displayed values?
    – nemec
    Oct 11 '20 at 2:17
0

@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:%02d\n", 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.

0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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