Giancarlo Ventura
Giancarlo Ventura

Reputation: 857

Add a job to cron and execute every 1h and x mins

I would like to execute a cronjob every 1 hour and x mins

I tried adding to crontab:

*/53 */1 * * * /myscrop.sh

But the scrip is executed every 53 mins and not 1h and 53 mins

Upvotes: 0

Views: 85

Answers (2)

paxdiablo
paxdiablo

Reputation: 882396

With "regular" crontab entries, this is rather difficult to do without a large number of them.

Since you want your job to happen every 1h:53m (113m), you may just be able to run every minute but with a suitable step value, something like:

*/113 * * * command-to-run

although I've never tested this with large skip values like that.

If that works, it's probably the easiest solution.

If you're running in an environment where that doesn't work, you can revert to the trick of actually running the script every minute but having it decide whether or not it does the actual "payload" of the task.

To do this, use a state file to record the last time the payload was run. Though the script itself runs very often, the payload only runs when enough time since the last has passed.

For example, the following script only runs the payload (the final echo) every seven seconds, regardless of how often the script is called:

#!/bin/bash

# Configuration items.

stateFile=/tmp/lastPayload # File holding time of last payload run.
minGap=7                   # How often payload should run (seconds).

# Get last payload time (checks for non-valid data).

((lastTime = 0))
[[ -f ${stateFile} ]] && lastTime="$(cat ${stateFile})"
[[ "${lastTime}" =~ [1-9][0-9]* ]] || ((lastTime = 0))

# Exit if not enough time since last payload run.

thisTime=$(date +%s)
((timeGap = thisTime - lastTime))
[[ ${timeGap} -lt ${minGap} ]] && exit

# Update last payload run time and execute payload.

echo ${thisTime} >${stateFile}
echo "[${lastTime}] [${thisTime}] [${timeGap}]"

If that script is called test_periodic.sh, you can test it with:

while true ; do ./test_periodic.sh ; sleep 1 ; done

This will run it every second but you'll notice the payload is only done every seven seconds (other than the first time), as expected:

[0] [1504041523] [1504041523]
[1504041523] [1504041530] [7]
[1504041530] [1504041537] [7]
[1504041537] [1504041544] [7]

For 1h:53m, set minGap to be 6780 (113 minutes, in seconds) and have cron run the script every minute.

Upvotes: 1

Christian Pekeler
Christian Pekeler

Reputation: 1070

Cron doesn't add the hours and minutes for the interval. */53 */1 * * * runs at 1:53, 2:53, 3:53, etc.

You'd have to create separate schedules. For a 53 minute interval, the set would look as follows:

0 0 * * * /myscrop.sh
53 0 * * * /myscrop.sh
46 1 * * * /myscrop.sh
39 2 * * * /myscrop.sh
32 3 * * * /myscrop.sh
25 4 * * * /myscrop.sh
18 5 * * * /myscrop.sh
11 6 * * * /myscrop.sh
4 7 * * * /myscrop.sh
57 7 * * * /myscrop.sh
50 8 * * * /myscrop.sh
43 9 * * * /myscrop.sh
36 10 * * * /myscrop.sh
29 11 * * * /myscrop.sh
22 12 * * * /myscrop.sh
15 13 * * * /myscrop.sh
8 14 * * * /myscrop.sh
1 15 * * * /myscrop.sh
54 15 * * * /myscrop.sh
47 16 * * * /myscrop.sh
40 17 * * * /myscrop.sh
33 18 * * * /myscrop.sh
26 19 * * * /myscrop.sh
19 20 * * * /myscrop.sh
12 21 * * * /myscrop.sh
5 22 * * * /myscrop.sh
58 22 * * * /myscrop.sh
51 23 * * * /myscrop.sh

And note that the interval always restarts at the beginning of the day.

Upvotes: 0

Related Questions