How do I set up a cronjob that runs every 25th hour?
-
1What is the purpose of this? Why is 24 hours not acceptable? – Mike Cooper Sep 13 '09 at 07:54
-
See also: http://stackoverflow.com/questions/745901/how-to-do-a-cron-job-every-72-minutes – mob Jun 17 '10 at 19:43
-
2Came here from Google with a legit use case, which is to avoid exceeding a daily API limit for a periodic job that's not especially time-sensitive. Adding an extra hour to be conservative and avoid daylight savings bugs. – mahemoff Apr 08 '13 at 12:16
6 Answers
Just a guess, but you don't
Best hack off the top of my head: write a script to track the last time it was run, and conditionally run it if it was more than 25 hours ago.
Cron that driver script to run every hour.

- 61,857
- 6
- 82
- 92
It would be easier to issue an at
command specifying the time and date of the next job when you start the current one but you could simulate that with a cronjob by updating the cronjob entry for the process at the start of the current run (not at the end 'cos then you'd have to take into account the time to run the job).

- 1,107
- 1
- 11
- 18
-
The `at` trick can fail if you miss one job, e.g., if the system is down when it's scheduled to run. – Keith Thompson Jun 11 '13 at 03:50
Setup a hourly job and check in your script if 25 hours are past with this snipnet:
if [ $((((`date +%s` - (`date +%s` % 3600))/3600) % 25)) -eq 0 ] ; then
your script
fi

- 1,645
- 2
- 11
- 9
-
2More comments would be appreciated. This code generate timestamp (seconds since epoch), converts it to hours and checks modulo 25 (hence every 25 hours). If needed change "-eq 0" to "-eq 10" to change hour in specific day... – darkless Jul 01 '13 at 08:59
You can achieve any frequency if you count the hours(, minutes, days, or weeks) since Epoch, add a condition to the top of your script, and set the script to run every hour on your crontab:
#!/bin/bash
hoursSinceEpoch=$(($(date +'%s / 60 / 60')))
# every 25 hours
if [[ $(($hoursSinceEpoch % 25)) -ne 0 ]]; then
exit 0
fi
date(1)
returns current date, we format it as seconds since Epoch (%s
) and then we do basic maths:
# .---------------------- bash command substitution
# |.--------------------- bash arithmetic expansion
# || .------------------- bash command substitution
# || | .---------------- date command
# || | | .------------ FORMAT argument
# || | | | .----- formula to calculate minutes/hours/days/etc is included into the format string passed to date command
# || | | | |
# ** * * * *
$(($(date +'%s / 60')))
# * * ---------------
# | | |
# | | ·----------- date should result in something like "1438390397 / 60"
# | ·-------------------- it gets evaluated as an expression. (the maths)
# ·---------------------- and we can store it
And you may use this approach with minutely, hourly, daily, or monthly cron jobs:
#!/bin/bash
# We can get the
minutes=$(($(date +'%s / 60')))
hours=$(($(date +'%s / 60 / 60')))
days=$(($(date +'%s / 60 / 60 / 24')))
weeks=$(($(date +'%s / 60 / 60 / 24 / 7')))
# or even
moons=$(($(date +'%s / 60 / 60 / 24 / 656')))
# passed since Epoch and define a frequency
# let's say, every 13 days
if [[ $(($days % 13)) -ne 0 ]]; then
exit 0
fi
# and your actual script starts here

- 271
- 4
- 4
You could use the 'sleep' or 'watch' commands to have a script run in a loop. Just make sure you script is executed.

- 191
- 1
- 2