Cron 表达式每 N 分钟运行一次 [英] Cron expression to run every N minutes

查看:370
本文介绍了Cron 表达式每 N 分钟运行一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要构建一个 cron 表达式,以便在用户点击开始按钮后每 10 分钟运行一次作业.

I need to build a cron expression to run a job every 10 minutes after the user click on start button.

我正在尝试执行以下操作:

I'm trying to do something like:

0 42/10 * * * ? *

而 42/10 就像用户点击开始于 hh:42(例如:18h42).下一个时间表是这样的:

And 42/10 is like the user click to start at hh:42 (example: 18h42). The next schedule is like:

1.  Friday, March 20, 2015 6:42 PM
2.  Friday, March 20, 2015 6:52 PM
3.  Friday, March 20, 2015 7:42 PM
4.  Friday, March 20, 2015 7:52 PM
5.  Friday, March 20, 2015 8:42 PM

问题是在第二次执行后,作业等待了一个小时才能执行下一次执行.如何构建一个立即启动并在 N 分钟后仍然运行的 cron 表达式?

The problem is after second execution, the job waits like a hour to perform the next execution. How can i build a cron expression that starts immediately and after still running after N minutes?

提前致谢.

推荐答案

如果你想每 n 分钟运行一次 cron,有两种情况需要考虑:

If you want to run a cron every n minutes, there are two cases to consider :

  • n 分钟(60 可被 n 整除)
  • n分钟从分钟开始YYYY-MM-DD HH:MM:00(通用)
  • Every nth minute (60 is divisible by n)
  • Every nth minute starting from minute YYYY-MM-DD HH:MM:00 (generic)

后一种情况是一种通用情况,涵盖了 60 不能被 n 整除的情况.提到这个案例需要一个开始时间".通过一些简单的数学运算,您很快就会明白为什么会这样.

The latter case is a generic case and covers the case where 60 is not divisible by n. It is mentioned that this case needs a "begin-time". With some simple math, you quickly figure why this is.

为此,我们使用定义范围和步长值的组合:

For this we use the combination of defining a range and a step value:

man 5 crontab: 步长值可以与范围结合使用.在带有 / 的范围之后指定跳过范围内的数字值.例如,可以使用 0-23/2在小时"字段中指定每隔一小时执行一次命令(V7 标准中的替代方案是0,2,4,6,8,10,12,14,16,18,20,22).也允许步长值在星号之后,因此如果指定每两小时运行一次作业,你可以使用 */2.

man 5 crontab: Step values can be used in conjunction with ranges. Following a range with /<number> specifies skips of the number's value through the range. For example, 0-23/2 can be used in the 'hours' field to specify command execution for every other hour (the alternative in the V7 standard is 0,2,4,6,8,10,12,14,16,18,20,22). Step values are also permitted after an asterisk, so if specifying a job to be run every two hours, you can use */2.

请参阅以下示例:

# Example of job definition:
# .----------------- minute (0 - 59)
# |   .------------- hour (0 - 23)
# |   |  .---------- day of month (1 - 31)
# |   |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |   |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |   |  |  |  |
# *   *  *  *  *   command to be executed
  m/n *  *  *  *   command1

这里,command1 将从 m 到 59 每 n 分钟执行一次.

Here, command1 will be executed every nth minute from m till 59.

这意味着:

  • 如果 m<=n,它们将始终间隔 n 分钟.例如.m=2,n=10 :: 作业将在几分钟内运行 2,12,22,32,42,52
  • 如果 m>n,它们将始终间隔 n 分钟,除了在小时的开始.例如.m=12,n=10 :: 作业将在 12,22,32,42,52 分钟内运行.所以这里我们在 52nd 和 12 分钟之间有 20 分钟的跳跃.
  • if m<=n, they will always be spaced by n minutes. Eg. m=2,n=10 :: the job will run on minutes 2,12,22,32,42,52
  • if m>n, they will always be spaced by n minutes, except at the start of the hour. Eg. m=12,n=10 :: the job will run on minutes 12,22,32,42,52. So here we have a jump of 20 minutes between the 52nd and 12th minute.

注意:你清楚地看到,如果n不能完美地整除60,你就会有问题.例如.m=0,n=110,11,22,33,44,55 上运行,所以距离下一次运行只有 5 分钟,而不是 11.

note: you clearly see that if n does not divide 60 perfectly, you will have problems. Eg. m=0,n=11 runs on 0,11,22,33,44,55, so we only have 5 minutes to the next run and not 11.

这种情况是通用的,涵盖了 60 的不可整除性.

This case is generic and covers the non-divisibility of 60.

这里变得更有趣,需要采取不同的方法.当您从某一天有一个连续的计数器时,这可以解决.输入 UNIX 时间戳,自 1970-01-01 00:00:00 UTC 以来的总秒数.假设我们想从 McFly 到达 Riverdale 的那一刻开始:

Here it gets more interesting and a different approach needs to be made. This can be resolved when you have a continuous counter from a given day. Enter UNIX time stamp, the total seconds since 1970-01-01 00:00:00 UTC. Let's say we want to start from the moment McFly arrived in Riverdale:

% date -d '2015-10-21 07:28:00' +%s 
1445412480

对于在2015-10-21 07:28:00"之后每 7 分钟运行的 cronjob,crontab 将如下所示:

For a cronjob to run every 7th minute after `2015-10-21 07:28:00', the crontab would look like this:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
  *  *  *  *  *   mintestcmd "2015-10-21 07:28:00" 7 && command2

mintestcmd 定义为

#!/usr/bin/env bash
starttime=$(date -d "$1" "+%s")
# return UTC time
now=$(date "+%s")
# get the amount of minutes
delta=$(( (now - starttime) / 60 ))
# set the modulo
modulo=$2
# do the test
(( delta % modulo == 0))

备注: UNIX 时间以 UTC 给出.如果您的 cron 运行在受夏令时影响的不同时区,建议不要在 2 点到 3 点之间运行命令.这可以跳过命令或运行命令两次(取决于时间是向前还是向后跳跃)

Remark: UNIX time is given in UTC. If your cron runs in a different time-zone which is influenced by daylight saving time, it is advisable not to run the command between 2 and 3 o'clock. This could skip the command or run the command twice (depending if the time jumps forward or backwards)

备注: UNIX 时间不受闰秒的影响

Remark: UNIX time is not influenced by leap seconds

备注: cron 没有亚秒级精度

这篇关于Cron 表达式每 N 分钟运行一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆