Cron jobs and random times, within given hours

Yeah, yeah, the question is over a year old, but maybe I can add something useful:

How to cron something at a random offset 20 times a day between 9am and 11pm? That’s kinda tricky within cron, because you are dividing 14 hours by 20 execution times. I don’t like the other answers very much because they require writing a bash wrapper script for your php script.

However, if you’ll allow me the liberty to ease the timing and frequency restriction to 13 times between 8:30am and 11:09pm, this might do the trick, and all within the confines of your crontab:

30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php

${RANDOM:3:2} uses bash’s $RANDOM that other people have mentioned above, but adds bash array slicing. Since bash variables are untyped, the pseudo-random signed 16-bit number gets truncated to the first 2 of its 5 decimal digits, giving you a succinct one-liner for delaying your cronjob between 10 and 99 minutes (though the distribution is biased towards 10 to 32).

The following might also work for you, but I found it do be “less random” for some reason (perhaps Benford’s Law is triggered by modulating pseudo-random numbers. Hey, I don’t know, I flunked math… Blame it on bash!):

30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php

You need to render modulus as ‘\%’ above because cron (well, at least Linux ‘vixie-cron’) terminates the line when it encounters an unescaped ‘%’.

Maybe you could get the remaining 7 script executions in there by adding another line with another 7-hour range. Or relax your restriction to run between 3am and 11pm.

Leave a Comment