在 Crontab 中以通用方式指定每 n 分钟,其中 n > 60

在 Crontab 中以通用方式指定每 n 分钟,其中 n > 60

在 crontab 中,我看到了几个答案,用户要求每 5 分钟运行一次:

*/5 * * * * command

或者每 5 分钟偏移一次:

10-59/5 * * * * command

我见过一些有创意的解决方案,人们每 90 分钟制定 2 行 crontab:

0 0-21/3 * * * whatever
30 1-22/3 * * * whatever

感谢以下其中一个答案(感谢@khaled),这是 3h30mins 的另一个创造性的解决方案:

0 0-23/7 * * * whatever
30 3-23/7 * * * whatever

有没有针对每 x 分钟问题的通用解决方案?例如,我目前需要每 3 小时 30 分钟。

解决重复标签的问题:链接的问题显然不同 - 有关于如何设置和调试 cron 作业的一般建议。我指的是一个特定问题,我们达到了 cron 语法的极限。我正在寻找一种解决“每超过 60 分钟”问题的通用算法,而链接的问题没有解决这个问题。

答案1

您只需要自己计算一下,就能算出实现时间安排所需的工作。

0 0-23/7 * * * whatever
30 3-23/7 * * * whatever

从这两个例子(有 30 分钟偏移时)可以得出一个简单的算法:

  • 添加两个条目:一个偏移量为 0 分钟,另一个偏移量为 30 分钟。
  • 指定小时范围宽度等于duration * 2
  • 指定小时偏移量:一个从 0 开始,另一个从丢弃 30 分钟部分后的持续时间开始。

如果你再多想一想,你就可以每隔 75 分钟就想出类似的解决方案。

编辑:

Cron 不能用于所有类型的计划作业。例如,每月在月末执行一次作业。您不能简单地使用 cron 来执行此操作,因为月末的日期会随月份而变化。为了解决这个问题,您可以在月末的可能值范围(28-31)内运行 cron 作业,并在执行实际作业之前验证它是否确实是月末的日期。

答案2

放置命令的结果

date +%s

在你的 crontab 中的一个变量中。比如 TIME=1497950105。现在在你的 crontab 中你需要一个条目,比如

* * * * * /bin/bash -c '[[ $(($(date +\%s)-TIME)) -gt seconds ]] && TIME=$(date +\%s) && whatever'

其中,秒是您想要的秒数(在您的情况下为 12600)。

或者如果你想在程序完成后等待 3 小时 30 分钟

* * * * * /bin/bash -c '[[ $(($(date +\%s)-TIME)) -gt seconds ]] && whatever && TIME=$(date +\%s)'

编辑: 我修正了我之前的回答:

  • 您必须使用 \ 来转义 % 符号,因此%s变成\%s
  • 您必须在命令前加上 /bin/bash -c

另一个解决方案(不使用 TIME)是:

 * * * * * /bin/bash -c '[[ $((($(date +\%s) / 60) % minutes)) -eq 0 ]] && whatever'

在您的情况下,分钟数是 210。

编辑2:

根据 MSalters 的建议,最好每 N 分钟运行一次条目,其中 N 是 60 和您的时间间隔(以分钟为单位)之间的最大公约数

答案3

在这种情况下,我认为您只是想使用 cron 来做一些它自己无法做到的事情(当然,cron 实际上定期执行辅助脚本的解决方案除外,在这种情况下,我认为不是 cron 本身在解决问题)。

间隔为 3 小时 30 分钟的解决方案并不完全正确。这是给出的解决方案:

0 0-23/7 * * * whatever
30 3-23/7 * * * whatever

这是错误的,因为 cron 将在 21:00 和 00:00 运行该作业,这是一个 3 小时的间隔,而不是 3 小时 30 分钟。

所有时间间隔的通用解决方案必须能够处理不能均匀划分为 24 小时的情况。虽然它不能均匀划分为 24 小时,但它可以均匀划分为一周!最简单的思考方式是做两组重叠的“每 7 小时”,如下所示:

0 0-23/7 * * 1 whatever
0 4-23/7 * * 2 whatever
0 1-23/7 * * 3 whatever
0 5-23/7 * * 4 whatever
0 2-23/7 * * 5 whatever
0 6-23/7 * * 6 whatever
0 3-23/7 * * 7 whatever
30 3-23/7 * * 1 whatever
30 0-23/7 * * 2 whatever
30 4-23/7 * * 3 whatever
30 1-23/7 * * 4 whatever
30 5-23/7 * * 5 whatever
30 2-23/7 * * 6 whatever
30 6-23/7 * * 7 whatever

能被一周整除的数就是你能做到的最好,因为月份与星期并不完全一致,而这是唯一可行的方法。例如,在一行 crontab 中,精确地每 12 分钟间隔是微不足道的,但精确地每 11 分钟间隔是不可能的,因为 10080 不能被 11 整除。(10080 是一周的分钟数)。

编写一种算法来解决这种情况肯定是可能的,但显然没有什么价值,尤其是考虑到解决方案的实际样子。

相关内容