Shell script to generate daily crontab entries between to specific dates

Hi,

I am currently writing a shell script to enter daily reoccurring jobs into the crontab. I want to be able to specify any two dates for which I want these daily jobs to run between.

Below is an example of what I need to be written to crontab.

# Give a start day of 21/10/2009 09:00 and end day of 23/10/2009 09:00, we need the following crontab entries:

# 00 09 22 10 0-7 script.sh 10/21/2009 10/22/2009
# 00 09 23 10 0-7 script.sh 10/22/2009 10/23/2009

Currently, I am assuming that the two date span within a month, but I want to extend this so that the dates can span across any time frame.

How would I go about running through all the days between 2 particular dates?

Any help would be much appreciated.

Thanks,

Jess

For example, you need run the script between 11/26/2009 and 11/28/2009 at 9 o'clock.

0 9 * * * script.sh 11/26/2009 11/28/2009

You can adjust your cronjob with different dates.

You need add some if-then-fi in your script.sh (code is not tested)

if [ "$2" = "" ]; then
  echo " please provide dates: $0 Date1 Date2"
  exit
fi

D1=`gdate -d "$1" +%s`
D2=`gdate -d "$2" +%s`
NOW=`gdate +%s`

if [ "${D1}" > "${D2}"] ; then
  echo "Date1 must older than Date2"
  exit
fi

if [ "$NOW" > "${D1}" && "$NOW" < "${D2}" ]; then

  # Put your script here.

fi

You can generally specify ranges and lists for the 3rd field i.e. day of the month. Check your man page for confirmation though.

So, for this case -

# Give a start day of 21/10/2009 09:00 and end day of 23/10/2009 09:00, we need the following crontab entries:

# 00 09 22 10 0-7 script.sh 10/21/2009 10/22/2009
# 00 09 23 10 0-7 script.sh 10/22/2009 10/23/2009

the following crontab entry is sufficient:

0 9 22,23 10 * script.sh
 

I have assumed that the input date parametes were passed only for the date-check criterion. If they are actually used in your script for some other purpose, then you'll have to pass them.

Crontab entries for this case are simple. As an example, if you want to run a script at 9 AM on the 3rd, 5th, 15th, and 28th day and all days from 18th through 23rd of October, then you can mix lists (d1, d2, d3) and ranges (d1-d2, d3-d4) thusly:

0 9 3,5,15,18-23,28 10 * script.sh
  

A "*" for "day of week" (5th field) means that the day of week is disregarded.

Things are not as simple for this case. In general, you can do this:

* * * * * <date_check_script> && script.sh

The <date_check_script> is a shell script that returns 0 if today lies within the intended date-range (the date-range might span a year or two, for example).

If the script is to be run at 9 AM every day from, say, 1-Nov-2009 through 30-Jun-2010, then you could have this:

0 9 * 1-6,11-12 * <date_check_script> && script.sh
 

and your <date_check_script> should return 0 if
(a) current month is [11,12] and year is 2009, or
(b) current month is [1-6] and year is 2010.

So you could have something like this:

$ 
$ # Note that the input parameter, the "-d" option of date and the printf commands are just for testing
$ # You can simply work with yr=$(date +%Y) and mon=$(date +%m)
$ # to consider date as "now"
$ cat -n date_check.sh       
     1  #!/bin/bash          
     2  YFMT=$1              
     3  yr=$(date -d "$YFMT" +%Y)
     4  mon=$(date -d "$YFMT" +%m)
     5  printf "year = $yr\tmon  = $mon\t"
     6  if [ "$mon" -ge "11" ] && [ "$yr" -eq "2009" ]; then
     7    # echo "mon ge 11 and yr eq 2009 ; return 0"      
     8    return 0                                          
     9  elif [ "$mon" -le "06" ] && [ "$yr" -eq "2010" ]; then
    10    # echo "mon le 06 and yr eq 2010 ; return 0"        
    11    return 0                                            
    12  else                                                  
    13    # echo "Outside range [1-Nov-2009, 30-Jun-2010] ; return 1"
    14    return 1                                                   
    15  fi                                                           
    16                                                               
$                                                                    
$ # now test the date_check.sh script
$ for i in jan feb mar apr may jun jul aug sep oct nov dec; do
>   . date_check.sh "1 $i 2009" ; echo "Return Value = $?"
> done
year = 2009     mon  = 01       Return Value = 1
year = 2009     mon  = 02       Return Value = 1
year = 2009     mon  = 03       Return Value = 1
year = 2009     mon  = 04       Return Value = 1
year = 2009     mon  = 05       Return Value = 1
year = 2009     mon  = 06       Return Value = 1
year = 2009     mon  = 07       Return Value = 1
year = 2009     mon  = 08       Return Value = 1
year = 2009     mon  = 09       Return Value = 1
year = 2009     mon  = 10       Return Value = 1
year = 2009     mon  = 11       Return Value = 0
year = 2009     mon  = 12       Return Value = 0
$
$ # and for year 2010
$ for i in jan feb mar apr may jun jul aug sep oct nov dec; do
>   . date_check.sh "1 $i 2010" ; echo "Return Value = $?"
> done
year = 2010     mon  = 01       Return Value = 0
year = 2010     mon  = 02       Return Value = 0
year = 2010     mon  = 03       Return Value = 0
year = 2010     mon  = 04       Return Value = 0
year = 2010     mon  = 05       Return Value = 0
year = 2010     mon  = 06       Return Value = 0
year = 2010     mon  = 07       Return Value = 1
year = 2010     mon  = 08       Return Value = 1
year = 2010     mon  = 09       Return Value = 1
year = 2010     mon  = 10       Return Value = 1
year = 2010     mon  = 11       Return Value = 1
year = 2010     mon  = 12       Return Value = 1
$
$

HTH,
tyler_durden