5

I need a certain script to run once a month (others viewing this question may need it to be run once a day/week/year/5-day, etc).

I know I can use cron to do so with:

0 0 1 * * ./script.sh

But what if the machine happens to be offline during that interval (power out on the 1st of a particular month as an example).

Is there an elegant solution to this? Or Would I have to include a sub-routine in that script to set an I've-run-this-month-already value, and then another script run every day of the month (or on boot) to check that value?

Update:

I need my script to run once per month at the very beginning of the month. While writing a script to accomplish a number of things, I created the below piece of code. I'm only putting it here in case someone finds it useful after finding this question.

# CHECK FOR THE OLD_MONTH FILE
if [ ! -e /usr/local/bin/system/old_month ]; then
        # CREATE IT IF IT DOESN'T EXIST WITH THIS MONTHS DATE
        echo `date` | awk '{print $2,$6}' > /usr/local/bin/system/old_month
fi

# CREATE A NEW FILE EVERY TIME THIS SCRIPT IS RUN WITH THIS MONTHS DATE
echo `date` | awk '{print $2,$6}' > /usr/local/bin/system/this_month

# CHECK IF OLD_MONTH AND THIS_MONTH ARE NOT THE SAME
if ! cmp /usr/local/bin/system/this_month /usr/local/bin/system/old_month > /dev/null 2>&1 ;
then
        # RUN YOUR RELEVANT CODE HERE #
        echo `date` | awk '{print $2,$6}' > /usr/local/bin/system/old_month     # UPDATE THE VALUE IN OLD_MONTH SO THAT THEY WILL MATCH NEXT TIME
fi
  • 1
    For a completely different approach to this problem, you could use a configuration management tool—namely, CFEngine—designed for "best effort" compliance and convergence to the desired state. Complete overkill if this is the only use you would make of it, but I use CFEngine all the time and it was my instant thought on seeing this question. – Wildcard Jul 25 '16 at 11:03
10

You can use Anacron for this, it is designed to run jobs at certain intervals without assuming that the system is on continuously. If a job is supposed to be run every month, Anacron will check whether it has run in the previous month, and run it if it hasn't (and remember that it doesn't need to run it again for another month).

In Debian derivatives, Anacron works nicely with Cron to take care of /etc/cron.{daily,weekly,monthly} appropriately (so you simply define your monthly task as a monthly job in /etc/cron.monthly, and it will be run appropriately).

On other systems, you would define your monthly task in /etc/anacrontab.

  • Nice! Installing now (keep mistyping it with an "h") to check it out. – Jim Jun 29 '16 at 9:13
  • Also any idea if anacron plays nicely with moreutils's chronic (I'm going to assume it does for now) – Jim Jun 29 '16 at 9:19
  • @Jim AFAIK it does. – Stephen Kitt Jun 29 '16 at 9:37
5

It seems fcron is the right tool: "fcron makes no assumptions on whether your system is running all the time or regularly : you can, for instance, tell fcron to execute tasks every x hours y minutes of system up time or to do a job only once in a specified interval of time."

  • I like what I'm reading about fcron (especially the fact that it works very similarly to cron. It's a pity that it has to be installed manually (not via apt-get) though. – Jim Jun 29 '16 at 9:41
  • It used to be available in Debian but was removed through lack of maintenance and difficulties upgrading the SELinux support. But fcron does appear to offer more features than the Anacron+Cron pair! – Stephen Kitt Jun 29 '16 at 10:57
  • Thanks for that! I've installed it for the time being, and will definitely be testing it out in the future. – Jim Jun 30 '16 at 10:33
  • So I finally got around to trying to use fcrontab. I've added the following lines: LINE1: !bootrun(1) LINE2: & 0 0 1 * * chronic /usr/local/bin/system/monthly_reset.sh Would that do the job? I'm struggling to find good examples of what I need done. – Jim Jul 4 '16 at 9:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.