Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a stopwatch Bash script to constantly display elapsed time?

You can think of this like a really simple stopwatch. I'm trying to hack together a bash script that displays the elapsed time since a specified date and updates the output every second.

First, Inside the script you'd specify a UNIX date: Fri Apr 14 14:00:00 EDT 2011. This would be when the stopwatch starts.

Now, when you run the script, you'd see...

06d:10h:37m:01s

and a few seconds later you'd see...

06d:10h:37m:05s

I'm not trying to have a new line printed for every second that elapses. The script should only have 1 line of output, and update it every second. Obviously you could quit the script and start it up again at any time, and it would still be right on since the starting time is hard coded.

Any ideas?

like image 356
jerzy Avatar asked Jan 16 '23 21:01

jerzy


1 Answers

I use the following code snippet in long-running scripts. The timer runs in a function (separate process) which will be killed (trap) if the main process is terminated by a keybord interrupt. The output shows the time elapsed from the start of the timer:

... working [hh:mm:ss]  00:07:58

The snippet:

#===  FUNCTION  ================================================================
#          NAME:  progressIndicatorTime
#   DESCRIPTION:  Display a progress indicator with seconds passed.
#    PARAMETERS:  [increment]   between 1 and 60 [sec], default is 2 [sec]
#===============================================================================
function progressIndicatorTime ()
{
  declare default=2                                       # default increment [sec]
  declare increment="${1:-$default}"                      # 1. parameter or default
  declare format='\b\b\b\b\b\b\b\b%02d:%02d:%02d'         # time format hh:mm:ss
  declare timepassed=0
  declare seconds minutes hours

  [[ ! "$increment" =~ ^([1-9]|[1-5][0-9]|60)$ ]] && increment=$default
  printf " ... working [hh:mm:ss]  00:00:00"
  while : ; do                                            # infinite loop 
    ((seconds=timepassed%60))
    ((minutes=timepassed/60))
    ((hours=minutes/60))
    ((minutes=minutes%60))
    printf "$format" $hours $minutes $seconds
    sleep $increment || break                             # sleep ...
    ((timepassed+=increment))
  done
}    # ----------  end of function progressIndicatorTime  ----------

progressIndicatorTime &                                   # run progress indicator
declare progressIndicatorPid=${!}                         # save process ID
trap  "kill $progressIndicatorPid" INT TERM               # trap keyboard interrupt

#
# run long command
#

kill -s SIGTERM $progressIndicatorPid                     # terminate progress indicator
like image 155
Fritz G. Mehner Avatar answered Jan 29 '23 20:01

Fritz G. Mehner