views:

243

answers:

5

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

+1  A: 

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 :-).

Gary
Except you might as well be calling it daily: it's a little known fact that the day changes once a day. ;)
Isaac Hodes
he said 9am though
Gary
Thanks for your answerThough not a big deal, why to run a script every hour?I am rather looking for a weekly script to run every Sunday. But wondering if anybody has already done something similar.
ring bearer
I'm not experienced at cron, that's why, there's probably a better way. But polling your conditional script every hour would get you pretty close to 9am. Daily doesn't really tell you when it will run during the day, and you specified 9am.
Gary
+3  A: 

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...

thesunneversets
Yes, I just suggested about the same. Not sure why you got voted down on that...
Dirk Eddelbuettel
Sounds good - I chose more descriptive answer.
ring bearer
I concede that the points should go to the fullest answer. Just glad to have lost my downvote :D
thesunneversets
+4  A: 

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.

Dirk Eddelbuettel
+3  A: 

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.

Lukasz Stelmach
this is an excellent solution. you dont have to edit your program, just can do this hack in cron entry and achieve the requirement.
thegeek
+1  A: 

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).