My first solution to this was to execute date +%Y%m%d%H%M and put that format of numbers into a file, and run the script every minute from cron. Then if the date from the file matches the date command, the script would do something. Then it would update that file for the next day plus 3 minutes. Is there a better way to accomplish this?

The result would be that the script would run the first day at (for example) 4:00am then the second day it would run at 4:03am and the third day it would run at 4:06am. It would execute every minute, but only run (if block) at the correct time.

Is the question and my solution clear?


3 Answers 3


You can use the at command from within your script (or a wrapper). Give it the time to run the next iteration.

echo '/dir/scriptname' | at 'now + 1443 minutes'

Put that line as near as possible to the beginning of the script to reduce drift.

  • That is a great solution! But wouldn't it need to be 'now + 24 hours + 3 minutes'?
    – Elmer
    Jun 4, 2012 at 4:54
  • @Elmer: Oops! You are correct (except that you can't do running addition). I'll edit my answer. Jun 4, 2012 at 4:55
  • To avoid drift, tell the script what time it's supposed to run and let it add 24h 3m to that. Jun 4, 2012 at 5:06
  • @KeithThompson: But then you have to keep a counter and increment it. Jun 4, 2012 at 5:27
  • Here's a script I wrote to reschedule at jobs. It's not pertinent to the question, but it's tangentially related. Jun 4, 2012 at 5:32

You should use at instead of cron, it will allow you to run the task exactly once. It could then re-schedule itself.

Well, I'd like to suggest some improvement to your own solution - if you'd stick to it. It will, however, still require to run the script every minute via cron:

Instead of manipulating any setup or tracking when the script has run the last time, you could reach the same goal with the UNIX timestamp:

A day has 60*60*24 = 86400 seconds. If you add the 3*60 = 480 from your requirements, you have 86880 seconds - and that's exactly the interval you want your script to run. Inside the script you can now check whether the current UNIX time % (modulo) this number of seconds equals zero, and abort otherwise.

If you need to have an explicit first run, like the 5th of June, 2012, 4:00 AM, you can subtract the associated timestamp (1338861600) from the local time first, check that it's not less than zero and proceed with the difference...

Of course, you could also let the script modify it's own crontab entry, but that's risky and also kinda awkward.

  • Preferably it would run on boot/reboot and keep the correct sequence even in the case of a random reboot. Yes the script editing the crontab sounds risky... Can you explain more about Inside the script you can now check whether the current UNIX time % (modulo) this number of seconds equals zero, and abort otherwise.
    – Elmer
    Jun 4, 2012 at 5:00
  • The modulo operation returns the remainder from a division. So, if the reminder is zero, you know that the exact amount of seconds has been passed. See en.wikipedia.org/wiki/Remainder and en.wikipedia.org/wiki/Modulo_operation -- but this is just fancy stuff, I'd recommend the at command like Dennis did
    – mjhennig
    Jun 4, 2012 at 5:16
  • If you check the seconds, are you not risking that if the script check happens one second latter (maybe because the machine is doing a lot of work) it would "think" that it's not the right time to run? Jun 4, 2012 at 10:21
  • Of course. But as I said, this is just a fancy way to go "because one can" - at is probably the correct choice here..
    – mjhennig
    Jun 4, 2012 at 10:27
  • I thought I should warn in case someone wants to use it anyway. Since in that approach the script runs every minute, a 30 second interval after the target time seems reasonable ( UnixTime % 86880 < 30 )`. Jun 4, 2012 at 10:37

You can modify your script to check some flag file with time to run at first. If time matches to start time, then your script goes on, otherwise it ends with exit 0. And you can start it in cron even every minute (or once at 3 minutes, seems it may be enough for your case). Also you need your script to modify time of next run in flag file. That safe enough and you won't miss any start time even in case of random reboot.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .