I'd like to write a cron command so that a job would execute once at some random time during the week - is this possible without having the crontab modify itself? I've considered writing a function that, based on a random number generator, may or may not execute the task - but I'd like the command to definitely execute and there to be no second in the week that was more likely than any other second...
5 Answers
One quick solution is to write a cron script that is called once a week and delays itself for a random time (not longer than the week) before doing the real job, for example by using the following command (works for bash and zsh)
sleep $(($RANDOM/32768.*60*24*7))m
Use a combination of cron
and at
. Your crontabbed script will contain something similar to:
TIME=$(($RANDOM/32768.*60*24*7))m
at -f /usr/local/bin/scriptfile $TIME
In /usr/local/bin/scriptfile
have the commands you want to run.
A quick (and dirty, and BAD, see comments below) solution to that problem would be creating a bash script which would run everyday as a cron and designed as follow:
That shell script would have a 1/7 chance to run your command each day and would update the timestamp of a file each time it successfully runs (use 'touch' for that).
You would just have to check that the file is >7 days old to decide if you run the script beforehand ('find' can do the job here).
There must be a better way but I'm too tired to see it ^^
update: As Joe pointed this script has a big flaw in that it can (and will eventually) not run at all some weeks. Thus you should not use it but I'll leave it as a counter-example.
-
I think this might mess with the probabilities... also there's a small chance that the script doesn't run at all in the week :(– JoeFeb 7, 2012 at 17:03
lacqui is correct, but his explanation is a bit short.
cron:
0 15 * * 1 /home/myhome/cron/schedulerandomjob.bash
/home/myhome/cron/schedulerandomjob.bash:
#!/bin/bash
TIME="now + $(( RANDOM % (60*24*7) )) minutes "
at -f /path/to/your/script $TIME
cron runs once a week, scheduling an 'at' job which randomly occurs during the week. (nb. There's a corner-case here to watch for... it might be possible for the job to occur at the end of the week and the beginning of the week, which might cause two simultaneous executions. If it is important, subtract a few minutes from the modulo to be sure.
I put together a small script called weekrand
(looked online somewhere for advice, forgot where it was) that does just that:
#!/bin/bash
FLOOR=1
RANGE=10080 # number of minutes per week
number=0 #initialize
while [ "$number" -le $FLOOR ]
do
number=$RANDOM
let "number %= $RANGE" # Scales $number down within $RANGE.
done
sleep ${number}m
$@
So basically weekrand {some command} {parameters}
will randomly execute {some command}
with {parameters}
between 0 and 10080 minutes, i.e. within a week.
An example crontab
line using it:
0 0 1 * * nice -n 10 /usr/local/bin/weekrand /root/jobs/weekly_job