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.

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.
–
ElmerJun 4 '12 at 5:00

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?
–
João PortelaJun 4 '12 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..
–
mjhennigJun 4 '12 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 )`.
–
João PortelaJun 4 '12 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.