5

有没有办法将 cron 表达式设计为每 70 分钟或 210 分钟运行一次,即 > 60 分钟。我试图搜索这个,但找不到这个。

我终于使用了一个包装脚本,该脚本将进行所需的时间检查,每 5 分钟调用一次(或最佳重复时间)。

如何在 cron 表达式中完成这样的任务?

4

3 回答 3

1

每70分钟跑一次

* */1.1666

或者

每 210 分钟运行一次

* */3.5
于 2017-11-22T15:47:21.110 回答
0

这个答案与这个这个完全一样

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

  • nth 分钟 (60 可被 整除n)
  • 从(通用)开始的每n分钟YYYY-MM-DD HH:MM:00

后者涵盖了 OP 的情况,但为了保持通用性,我介绍了这两种情况。

nth 分钟 (60 可被 整除n)

这对 ( n=1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30)有效

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

man 5 crontab步长值可以与范围结合使用。跟随一个范围,/<number>指定跳过该范围内的数字值。例如, 0-23/2可以在“小时”字段中使用以指定每隔一小时执行一次命令(V7 标准中的替代方案是0,2,4,6,8,10,12,14,16,18,20,22)。星号后也允许使用步骤值,因此如果指定要每两小时运行一次的作业,您可以使用*/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 分钟执行一次。

这意味着 :

  • 如果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 和12thminute 之间有 20 分钟的跳跃。

注意:您清楚地看到,如果n不完美地划分60,您将遇到问题。例如。m=0,n=11继续运行 0,11,22,33,44,55,所以我们只有 5 分钟才能进行下一次运行。

n分钟从YYYY-MM-DDTHH:MM:00

如果你想每n分钟运行一次 cron,你不能用 cron 干净地做到这一点,但这是可能的。为此,您需要在测试检查时间的 cron 中进行测试。最好在查看 UNIX 时间戳(自1970-01-01 00:00:00 UTC. 假设我们想从 McFly 到达 Riverdale 的那一刻开始:

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

# 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 && command1
*/10 *  *  *  *   mintestcmd "2015-10-21 07:00:00"  70 && command2
*/30 *  *  *  *   mintestcmd "2015-10-21 07:00:00" 210 && command3

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 >= 0 )) && (( delta % modulo == 0))

在上面的例子中,我们有:

  • command12015-10-21 07:28:00将在, 2015-10-21 07:35:00, 2015-10-21 07:42:00, 2015-10-21 07:49:00, ...上每 7 分钟运行一次
  • command2以后每 70 分钟运行一次2015-10-21 07:00:00。由于 70 可以被 10 整除,并且开始时间完美地从整点开始,我们可以将 cron 设置为每 10 分钟运行一次。
  • command3以后每 210 分钟运行一次2015-10-21 07:00:00。由于 210 可以被 30 整除,并且开始时间完美地从整点开始,我们可以将 cron 设置为每 30 分钟运行一次。

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

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

备注: cron没有亚秒级精度

于 2018-04-17T10:03:48.323 回答
0

基本上,您需要每分钟运行一次 cron:

* * * * *

并让您的脚本确定其最后一次执行日期是在 70 分钟还是 210 分钟前。
如果是这样,它将继续脚本的其余部分。
如果没有,它将立即退出。

换句话说,不要尝试将所有内容都放在 cron 表达式中。

正如Keith Thompson评论的那样,您可以减少运行该脚本的频率 (0 0/5 0 ? * * *),在 70 分钟进行一次测试,或者每 30 分钟 ( 0 0/30 0 ? * * *) 在 210 分钟进行一次测试。

于 2017-10-23T20:40:38.090 回答