Run a command once in three hours

Hi All,

I have a bash script which is scheduled to run for every 20 minutes. Inside the bash script, one command which I am using need to be triggered only once in two or three hours.Is there anyway to achieve this.

For example,

if [ -f file ]
then
echo "hi"
else
echo "Hello"
UNIX Command---once in 3 hours
fi

In most cases file will not be there, so it will go to else portion and execute hello.. But this one I need to execute only once in 3 hours, instead of executing it every 20 minutes

Scheduled by cron ? On the exact hour, 20 min, and 40 min past? Or should it run only every ninth time the script is run?

And, what if the file is there when three hours are full? Execute the "Hi" and quit, i.e. NOT run the "UNIX Command"?

Hi it should run only every 9th time the script is running.If the file is there yes we need to execute hi and quit

This is an example of what is called "inter-process communication" because one process (the program to be started) needs some information of another process (the last instance of the program and when it ran lastly). There are only so many means for such inter-process communication:

  • semaphores
  • shared memory
  • message queues

In this case we need a "semaphore". Not a "UNIX semaphore" (in UNIX there is a certain OS feature implementing semaphores), but something alike. We simply put a file somewhere with the "UNIX date", the numbers of seconds passed since Jan 1st 1970, of when the program ran the last time:

#! /bin/ksh

typeset last="/tmp/myfile"

if [ -f file ] ; then
     echo "hi"
else
     echo "Hello"
     UNIX Command---once in 3 hours
     echo $(date +'%s') > "$last"
fi

exit 0

Now we just need to read this file if it is there (otherwise we are running for the first time) and make the starting of the program conditional to that. Notice that 10800 = 3x3600, 3 hours in seconds and 4294967295 is 2^^32-1:

#! /bin/ksh

typeset    last="/tmp/myfile"
typeset -i now=$(date +'$s')

if [ -f file ] ; then
     echo "hi"
else
     echo "Hello"
     if ! [ -f "$last" ] ; then
          echo "4294967295" > "$last"
     fi
     if (( now - 10800 <= $(cat $last) )) ; then
          UNIX Command---once in 3 hours
          echo $(date +'%s') > "$last"
     fi
fi

exit 0

I hope this helps.

bakunin

1 Like

Thanks a lot

Same principal approach as bakunin's, but mayhap a bit less resource consuming (no cat nor echo (i.e. opening time stamp file twice), just file system (meta data) operation, running date just once), given stat and date -d are available on your system:

if (( $(stat -c%Y $last) < $(date -d"3 hours ago" +%s) ))
 then  UNIX Command---once in 3 hours
       touch $last
fi
1 Like