bash : Make job every x days
I have a bash script runned every day via cron.
In this bash I want to run some command but only every x day (x is fixed and will be 3, 4 or 5 I don't know at the moment)
I can test if the remainder of the division day of month / x equal 0
day_of_month % x = 0
I will work on a single month but not always between to month, for example mo开发者_如何学Cnths april - may with x = 3
1 2 3 4 5 6 7 8 9 ... 27 28 29 30 31 1 2 3 4 5 6 7 8 9 ... 27 28 29 30
x x x ... x x x x x ... x x
It not a big deal, but is there any other way to do this ?
PS : I don't want to explode my script and make 2 cron jobs (one every day : *, the other evevery x day : */x)
One easy solution would be to use "day of year" instead of day of month. Then there'd be no problem with different month lengths. You'd still get problems at the end of year, of course.
The "day of year" is available via date +%j
.
If that is still not acceptable, you can use the seconds since 1970 (date +%s
), and divide by days*24*60*60, then use the remainder of that. You'd still get problems with leap seconds, but otherwise it should be correct.
Using cron sounds the like the proper idea actually, because that is what cron is made for.
One idea though to solve your 'across months' problems: don't think in months, instead check whether the time-in-seconds-since-epoch % x*seconds-per-day is 0 ...
I would export a system variable with last date of execution and calculate the interval from it. It wouldn't work after a restart but I assume in this case the interval should be restored.
Have a look at the at command
Using that you can tell a script to call itself at a later date.
From manpage:
For example, to run a job at 4pm three days from now, you would do at 4pm + 3 days, to run a job at 10:00am on July 31, you would do at 10am Jul 31 and to run a job at 1am tomorrow, you would do at 1am tomorrow.
If I had this problem, I would tell cron to run my script once every day, and inside the script I would calculate whether or not work needs to be done. That way, you have full control over it.
For example,
dayno=`date +%d`
let divided=daynum%3
if [ $divided == 0 ] ; then
exit 0
fi
# real work begins here
This script would work on any system that uses bash.
Does your job need to run every day? That is, does it do something on those days when your calculation does not result in a 0. If not, you could set up a job in cron thus:
0 12 3,6,9,12,15,18,21,24,27,30 * * <your job>
and it would run every third day (at 12 noon in my example).
I'm pretty sure that "Feb 30" would be safely ignored.
精彩评论