How do set cron to run my script every 40mins/25mi

2020-02-10 03:01发布

I want a script to run every 40mins beginning on the 40th minute.
so that means:

00:40, 01:20, 02:00, 02:40, 03:20...

So I made this entry to cron:

*/40 * * * * /path/to/script/foo.sh

Unfortunately this runs the script every 40th minute of the hour:

00:40, 01:40, 02:40...

The same goes with the script that I meant to run every 25mins.

Am I missing something here?


ANSWERS
Alright, in case you happen to drop by here having the same problem
here's how I solved it:

# 40mins-interval
40 0 * * * /path/foo.sh         (0)
0,40 2-22/2 * * * /path/foo.sh  (2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22)
20 1-23/2 * * * /path/foo.sh    (1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23)  


# 25mins-interval
25,50 0 * * * /path/foo.sh              (0)
0,25,50 5-20/5 * * * /path/foo.sh       (5, 10, 15, 20)
15,40 1-21/5 * * * /path/foo.sh         (1, 6, 11, 16, 21)
5,30,55 2-22/5 * * * /path/foo.sh       (2, 7, 12, 17, 22)
20,45 3-23/5 * * * /path/foo.sh         (3, 8, 13, 18, 23)
10,35 4-19/5 * * * /path/foo.sh         (4, 9, 14, 19)

Notes:
1. There will still be collisions in this schedule (i.e: see schedules that run on the 0th and 10th minutes on both intervals).
2. The script won't run at an exact interval from its last run today going on the next day (i.e: 25min interval ends @23:45 today, begins @00:25 next day).

标签: cron crontab
5条回答
三岁会撩人
2楼-- · 2020-02-10 03:20

You will need to add several entries for the same script to cron, one for running on the hour, one for twenty past and one for twenty to the hour.

0 0,2,4,6,8,10,12,14,16,18,20,22 * * * script
20 1,3,5,7,9,11,13,15,17,19,21,23 * * * script
40 0,2,4,6,8,10,12,14,16,18,20,22 * * * script

You say that it should start at 00:40, but the run of the previous day will be at 23:20. Do you want an 80 minute gap in runs around midnight?

查看更多
太酷不给撩
3楼-- · 2020-02-10 03:21

You can achieve any frequency if you count the minutes(, hours, days, or weeks) since Epoch, add a condition to the top of your script, and set the script to run every minute on your crontab:

#!/bin/bash

minutesSinceEpoch=$(($(date +'%s / 60')))

# every 40 minutes
if [[ $(($minutesSinceEpoch % 40)) -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 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 7 hours

if [[ $(($hours % 7)) -ne 0 ]]; then
    exit 0
fi

# and your actual script starts here
查看更多
唯我独甜
4楼-- · 2020-02-10 03:33

For the task you want to accomplish you have to write a little bit more complex entry in your crontab.

You see the pattern above?

00:40, 01:20, 02:00, 02:40, 03:20 and again 04:00, 04:40, 05:20, 06:00, 06:40, 07:20, 08:00

I can break it down into three entries:

  1. Every even hour you have to run it at 40th min
  2. Every odd hour you have to run it at 20th min
  3. Every even hour you have to run it on 0. (Except 0 hour)

You can accomplish this with more than one entries:

#1
*/40 0,*/2 * * * /path/to/script/foo.sh
#2
*/20 1,*/2 * * * /path/to/script/foo.sh
#3
0 2,*/2 * * * /path/to/script/foo.sh

NOTE: It might have minor issues, but there I gave you direction :)

PS: This will explain alot more

查看更多
做个烂人
5楼-- · 2020-02-10 03:39

It always splits the current hour only.

40/40 = 1 so it runs every 40th minute of an hour.

*/5 would do 5, 10, 15...

You should go for larger intervals.

Do */30 for your 25 minute interval and every 60 minutes for your 40 minutes interval.

Otherwise set up two crontabs for your script:

0,40 */2 * * * /path/to/script/foo.sh
20 1,3,5,7,9,11,13,15,17,19,21,23 * * * /path/to/script/foo.sh
查看更多
▲ chillily
6楼-- · 2020-02-10 03:40
#! /bin/sh

# Minute Cron
# Usage: cron-min start
# Copyright 2014 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

# Run this script under Cron once a minute

basedir=/etc/cron-min

if [ $# -gt 0 ]
then
   echo
   echo "cron-min by Marc Perkel"
   echo
   echo "This program is used to run all programs in a directory in parallel every X minutes."
   echo
   echo "Usage: cron-min"
   echo
   echo "The scheduling is done by creating directories with the number of minutes as part of the"
   echo "directory name. The minutes do not have to evenly divide into 60 or be less than 60."
   echo
   echo "Examples:"
   echo "  /etc/cron-min/1      # Executes everything in that directory every 1  minute"
   echo "  /etc/cron-min/5      # Executes everything in that directory every 5  minutes"
   echo "  /etc/cron-min/13     # Executes everything in that directory every 13 minutes"
   echo "  /etc/cron-min/75     # Executes everything in that directory every 75 minutes"
   echo
   exit
fi

for dir in $basedir/* ; do
   minutes=${dir##*/}
   if [ $(( ($(date +%s) / 60) % $minutes )) -eq 0 ]
   then
      for program in $basedir/$minutes/* ; do
     if [ -x $program ]
     then
        $program &> /dev/null &
     fi
      done
   fi
done
查看更多
登录 后发表回答