Hi I need to schedule a cron job to run at at 9:00 AM on first Sunday of every month. Did a little research and see that there is no short hand in cron to this. Do you know of an optimal way ? Using Bash+RHL
maybe use cron.hourly to call another script. That script will then check to see if it's the first sunday of the month and 9am, and if so, run your program. Sounds optimal enough to me :-).
A hacky solution: have your cron job run every Sunday, but have your script check the date as it starts, and exit immediately if the day of the month is > 7...
You need to combine two approaches:
a) Use cron
to run a job every Sunday at 9:00am.
00 09 * * 7 /usr/local/bin/once_a_week
b) At the beginning of once_a_week
, compute the date and extract the day of the month via shell, Python, C/C++, ... and test that is within 1 to 7, inclusive. If so, execute the real script; if not, exit silently.
You can put something like that in crontab
file:
00 09 * * 7 [ $(date +%d) -le 07 ] && /run/your/script
The date +%d
gives you number of current day and than you can check if the day is lesser or equal of 7.
If it is that run your command.
If you run these script only in Sundays it should mens that it runs only in the first Sunday of the month.
If you don't want cron to run your job everyday or every Sunday you could write a wrapper that will run your code, determine the next first Sunday, and schedule itself to run on that date.
Then schedule that wrapper for the next first Sunday of the month. After that it will handle everything itself.
The code would be something like (emphasis on something...no error checking done):
#! /bin/bash
#We run your code first
/path/to/your/code
#now we find the next day we want to run
nskip=28 #the number of days we want to check into the future
curr_month=`date +"%m"`
new_month=`date --date='$nskip days' +"%m"`
if [[ curr_month = new_month ]]
then
((nskip+=7))
fi
date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler
#schedule the job using "at"
at -m $date < /path/to/wrapper/code
The logic is simple to find the next first Sunday. Since we start on the first Sunday of the current month, adding 28 will either put us on the last Sunday of the current month or the first Sunday of the next month. If it is the current month, we increment to the next Sunday (which will be in the first week of the next month).
And I used "at". I don't know if that is cheating. The main idea though is finding the next first Sunday. You can substitute whatever scheduler you want after that, since you know the date and time you want to run the job (a different scheduler may need a different syntax for the date, though).