Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
up vote 8 down vote accepted

You could use the command 'at'

at now +4 hours -f commandfile


at now +$((($RANDOM % 10)+2)) hours -f commandfile
share|improve this answer
So schedule at to run every (say) 12 hours with cron, then have the at job happen a few hours later. Doable, though it would mean that the jobs happen more regularly than I want (no possibility of having it happen after 2 hours, then after 3 more hours after that, etc.). – Charles Jul 25 '14 at 16:37
Using this there is a 1 in 10 chance of it happening after only 2 hours, a 1 in 10 chance of it being after 3 hours, and so on up to 11 hours. $RANDOM % 10 will never return more than 9. – goldilocks Jul 25 '14 at 16:47
@Charles you can use 'seconds', 'mins' instead of 'hours' – jhilmer Jul 25 '14 at 17:01
@jhilmer: I want it to run repeatedly (in fact forever at these irregular intervals), not just once. – Charles Jul 25 '14 at 17:16
You could schedule the next job at the end of the current – jhilmer Jul 25 '14 at 17:23

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

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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