Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
Search Forums:



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

Closed Thread    
 
Thread Tools Search this Thread Display Modes
    #1  
Old 01-29-2009
Registered User
 

Join Date: Jan 2009
Location: Minneapolis, MN
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Display runnning countdown in a bash script?

I am looking for a way to display on a single line, a running countdown for a given amount of time in a terminal using a bash script.

I am looking for this to use as part of a larger bash script that captures Video. The script sets up a bunch of parameters for DVgrab, and one of the parameters set is the tape length. I would like to use this $tape_length as the input for a running countdown so that at any time during capture I can see how much longer the capture will run for.

On a side note, in my script $tape_length is entered in the form hh:mm:ss

I feel like this should be easy, but despite some extensive searching I can't find any leads or even scripts to steal and modify! Any help is much appreciated, I'm very new to bash scripting...
Sponsored Links
    #2  
Old 01-29-2009
Moderator
 

Join Date: Aug 2005
Location: Saskatchewan
Posts: 12,191
Thanks: 232
Thanked 1,703 Times in 1,632 Posts
This uses a few tricks to do what you want:
  • The printf command does NOT append a linefeed automatically unless you tell it to.
  • Setting IFS to something else lets the shell split things apart into arrays on whatever delimiter you want, in this case , :.
  • The date command can be used to produce time in seconds.
  • Carriage returns return the cursor to the beginning of the line without moving to the next line.


Code:
function countdown
{
        local OLD_IFS="${IFS}"
        IFS=":"
        local ARR=( $1 )
        local SECONDS=$((  (ARR[0] * 60 * 60) + (ARR[1] * 60) + ARR[2]  ))
        local START=$(date +%s)
        local END=$((START + SECONDS))
        local CUR=$START

        while [[ $CUR -lt $END ]]
        do
                CUR=$(date +%s)
                LEFT=$((END-CUR))

                printf "\r%02d:%02d:%02d" \
                        $((LEFT/3600)) $(( (LEFT/60)%60)) $((LEFT%60))

                sleep 1
        done
        IFS="${OLD_IFS}"
        echo "        "
}

countdown "00:07:55"

Sponsored Links
    #3  
Old 01-29-2009
Registered User
 

Join Date: Jan 2009
Location: Minneapolis, MN
Posts: 14
Thanks: 0
Thanked 0 Times in 0 Posts
Thanks!

That is exactly what I needed Thanks! At first it was counting down and then starting the capture, but I just added an "&" and she works great!

Timer

(Just wanted to include this for search purposes...)
    #4  
Old 03-30-2009
pvdb's Avatar
Registered User
 

Join Date: Mar 2009
Location: London, UK
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Quote:
Originally Posted by Corona688 View Post
This uses a few tricks to do what you want:
Great little script, Corona688, just what I needed!

Here's a little variant I wrote that allows you to prefix the countdown timer with a custom message:


Code:
countdown "00:07:55" Time left before entering the matrix

... which produces something like:


Code:
Time left before entering the Matrix > 00:00:08

Here's my patch:


Code:
pvdb@localhost ~ $ diff original prefix 
5c5,7
<         local ARR=( $1 )
---
>         local ARR=( $1 ) ; shift
>         IFS="${OLD_IFS}"
>         local PREFIX="$*" ; [ -n "${PREFIX}" ] && PREFIX="${PREFIX} > "
16c18
<                 printf "\r%02d:%02d:%02d" \
---
>                 printf "\r${PREFIX}%02d:%02d:%02d" \
21d22
<         IFS="${OLD_IFS}"
pvdb@localhost ~ $ _

Sponsored Links
    #5  
Old 03-30-2009
Moderator
 

Join Date: Aug 2005
Location: Saskatchewan
Posts: 12,191
Thanks: 232
Thanked 1,703 Times in 1,632 Posts
Great idea, thanks for the patch! But since your copy/paste of it wasn't identical down to the last bit of whitespace and newline(possible disagreement on spaces per tab, etc) I'm having trouble applying it... diff -U is generally preferred these days as it gives more complete information on what's being replaced where, but a full code-listing really can't be that much larger.

But I think I see a potential problem in your use of printf: if your PREFIX variable includes control sequences like %d it will cause printf to do strange things since it will insert parameters from the commandline. Try inserting %s instead of PREFIX, and making "${PREFIX}" the first argument printf is given. This will guarantee the string is printed as 100% literals.
Sponsored Links
    #6  
Old 03-30-2009
cfajohnson's Avatar
Shell programmer, author
 

Join Date: Mar 2007
Location: Toronto, Canada
Posts: 2,830
Thanks: 0
Thanked 82 Times in 76 Posts
Quote:
Originally Posted by Corona688 View Post

Code:
countdown "00:07:55"


That will fail for 00:08:09.

Here is my version, which will work in any POSIX shell:


Code:
countdown()
(
  IFS=:
  set -- $*
  secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} ))
  while [ $secs -gt 0 ]
  do
    sleep 1 &
    printf "\r%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60))
    secs=$(( $secs - 1 ))
    wait
  done
  echo
)

Sponsored Links
    #7  
Old 04-02-2009
pvdb's Avatar
Registered User
 

Join Date: Mar 2009
Location: London, UK
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Hi cfajohnson,

Thanks for your version of the script... very enlightening!

Quick question: instead of doing a "raw" sleep...


Code:
sleep 1

your version does this instead...


Code:
    sleep 1 &
    ...
    wait

I'm assuming doing it does way minimizes the "skew" on the actual time spent in the function, ie. every cycle is as close to 1 second as possible, as opposed to 1 second + however long it takes to do all the work.

Is that correct, or is there another benefit in doing it this way?

Regards,

PVDB
Sponsored Links
Closed Thread

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
passing variable from bash to perl from bash script arsidh Shell Programming and Scripting 10 06-04-2008 12:25 PM
long runnning processes more than one hour not able to see in ps -ef command shyam soni Shell Programming and Scripting 4 03-01-2008 11:46 AM
Bash Script to display directories in Path? debut Shell Programming and Scripting 1 11-09-2005 04:06 PM
shell script - loop to countdown froggwife UNIX for Dummies Questions & Answers 2 11-29-2001 09:48 AM



All times are GMT -4. The time now is 05:19 AM.