Schedule job at irregular intervals

It’s simple enough to use cron to schedule a job to occur periodically. I’d like to have something occur less regularly — say, run the job, then wait 2 to 12 hours before trying again. (Any reasonable type of randomness would work here.) Is there a good way to do this?

Asked By: Charles

||

You could use the command ‘at’

at now +4 hours -f commandfile

Or

at now +$((($RANDOM % 10)+2)) hours -f commandfile
Answered By: jhilmer

Option 1

Schedule your job in cron to run every hour (or every other hour), but prefix the job with something like this (presuming you have SHELL=/bin/bash in your crontab):

[ $[RANDOM % 12] -eq 0 ] || exit 0; YOUR_JOB_HERE

Then there will be an approximately* one in twelve chance of the job running each time its scheduled.

Option 2

Schedule a cron job that, at the start of the day, figures out some random times and uses at to schedule all of today’s runs. This is much more complicated, but will allow you to use different random distributions. E.g., you may want 2 hours to be much more likely than 12 hours.


Fine print

*This method of generating a random number is actually biased. The problem is that the maximum (32767) is not an even multiple of 12 (minus one). To see the problem clearly, compare if the maximum were 11 (12×1-1 = 11). 0 would yield 0, 1 would yield 1, etc. all the way through 11 yielding 11. But if it were 13 instead, 12 yields 0, and 13 yields 1. So 0 and 1 have two values that yield them, but 2–11 only have one value, so they’re less likely. Hence, its biased. Switching to a formula using division by the maximum doesn’t fix the problem, it just changes which numbers are biased against. Actual fixes are much more code (and basically involve faking the maximum being what you need it to be by trying again when it isn’t).

Answered By: derobert
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.