bash script for timer

16,191

Solution 1

Wrap your loop into an infinite loop (i.e. a while loop without conditions), and add a sleep 30 in this outer loop.

while :
do
    ###  < your
    ###   timer
    ###   here >
    sleep 30
done

I'd suggest you also remove the wait instruction and the & from "sleep 1 &". Also, print is not the right program to write to the terminal, use echo instead.

while :
do
    for ((i=30; i>0; i--))
    do
       sleep 1 
       echo -n "$i "
    done
    sleep 30
    echo ""
done

Be aware that this timer is not accurate as evaluating the loop instructions takes a (small, but non zero) amount of time. A solution using date would be preferable: see for example the countdown function here: https://superuser.com/a/611582.

Solution 2

I think you are looking for something like this:

#!/bin/bash

## Infinite loop
while :; do
        ## Run a sleep command for 30 seconds in the background
        sleep 30 &
        ## $! is the PID of the last backgrounded process, so of the sleep.
        ## Wait for it to finish.
        c=30
        while [[ -e /proc/$! ]]; do
                printf '%s\r' "$(( --c ))"
                ## For more precision, comment the line below. This causes the
                ## script to wait for a second so it doesn't spam your CPU.
                ## If you need accuracy, comment the line out. Although, if you
                ## really need accuracy, don't use the shell for this.
                sleep 1
        done
done

Alternatively, use date:

#!/bin/bash
waitTime=30;
## Infinite loop
while :; do
        startTime=$(date +%s)
        currentTime=$(date +%s)
        c=$waitTime;
        while [[ $((currentTime - startTime)) -lt $waitTime ]]; do
                printf '%s\r' "$(( --c ))"  
                ## For more precision, comment the line below. This causes the
                ## script to wait for a second so it doesn't spam your CPU.
                ## If you need accuracy, comment the line out. Although, if you
                ## really need accuracy, don't use the shell for this.
                sleep 1
                currentTime=$(date +%s)
        done
        c=0
        echo "";
done

For even greater precision, don't store the date in a variable:

#!/bin/bash
waitTime=4;
while :; do
        startTime=$(date +%s)
        c=$waitTime;
        while [[ $(($(date +%s) - startTime))  -lt $waitTime ]]; do
                printf '%s\r' "$(( --c ))"  
                sleep 1
        done
        c=0
done
Share:
16,191

Related videos on Youtube

sourav
Author by

sourav

Unix only

Updated on September 18, 2022

Comments

  • sourav
    sourav over 1 year

    I want to write a bash script to run a timer for 30 seconds and, after 30 seconds, it should hold for the next 30 seconds and again that timer will start for next 30 seconds and continue the same.

    for ((i=30; i>0; i--)); do
       sleep 1 &
       print "$i \r"
       wait
    done
    

    Using the code above, I can run the timer for 30seconds, but I need to hold for the next 30 seconds and again need to run the timer for the next 30 seconds.

    How can I do this?

    same thing I can do it in java using this code

    import java.util.Timer;
    import java.util.TimerTask;
    public class TestClass {
        static int count = 0;
        public static void main(String[] args)  {
            final TestClass test = new TestClass();
                    Timer timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            test.doStuff();
                          }
                    }, 0, 1000);
        }
        public void doStuff() {
            if (count == 30) {
                try {
                    Thread.sleep(30000);
                    count = 0;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(++count);
        }
    }
    
    • terdon
      terdon over 6 years
      I don't understand. How many 30 second periods do you need? You need to wait for 30 seconds and then do what? And then start it again? How many times should it run? Please edit your question and clarify.
    • sourav
      sourav over 6 years
      after running first 30seconds timer should hold for next 30seconds then timer should again start for next 30seconds. And this should continue @terdon