12

How do I set up a cronjob that runs every 25th hour?

Timmy
  • 12,468
  • 20
  • 77
  • 107
  • 1
    What 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
  • 2
    Came 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 Answers6

17

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.

timdev
  • 61,857
  • 6
  • 82
  • 92
7

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).

mas
  • 1,107
  • 1
  • 11
  • 18
2

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
Flavio
  • 1,645
  • 2
  • 11
  • 9
  • 2
    More 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
2

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
stefanmaric
  • 271
  • 4
  • 4
0

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

osmosis
  • 191
  • 1
  • 2
-1

I think you should try this

0 */25 * * * ...