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

use*_*910 9 linux cron

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

*/5 * * * * command
Run Code Online (Sandbox Code Playgroud)

或者每 5 分钟有一个偏移量:

10-59/5 * * * * command
Run Code Online (Sandbox Code Playgroud)

我见过一些创造性的解决方案,其中人们每 90 分钟制作 2 行 crontab:

0 0-21/3 * * * whatever
30 1-22/3 * * * whatever
Run Code Online (Sandbox Code Playgroud)

感谢以下答案之一(感谢@khaled),这是 3 小时 30 分钟的另一种创造性解决方案:

0 0-23/7 * * * whatever
30 3-23/7 * * * whatever
Run Code Online (Sandbox Code Playgroud)

是否有针对每 x 分钟问题的通用解决方案?例如,我目前需要每 3h30m。

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

Kha*_*led 10

您只需要自己进行数学计算即可提出实现您的时间所需的工作。

0 0-23/7 * * * whatever
30 3-23/7 * * * whatever
Run Code Online (Sandbox Code Playgroud)

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

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

如果你想得更多,你可以想出类似的解决方案,比如每 75 分钟一次。

编辑:

Cron 不能用于所有类型的预定作业。例如,每月的最后一天执行一次作业。您不能简单地使用 cron 来完成,因为每个月的最后一天都在变化。为了解决这个问题,您可以在一个月的最后一天 (28-31) 的可能值范围内运行 cron 作业,并在执行实际工作之前验证它是否真的是脚本中的最后一天。

  • 我还建议考虑 [systemd timers](https://www.freedesktop.org/software/systemd/man/systemd.timer.html),它可以作为 [cron 替代品](https://wiki. archlinux.org/index.php/Systemd/Timers)同时更加灵活(而且,是的,它[可以在一个月的最后一天](https://unix.stackexchange.com/questions/306336/how-to- configure-systemd-timer-to-run-the-service-on-last-day-of-the-month),尽管只有截至 2017 年的最新版本)。 (2认同)

Mar*_*ani 6

把命令的结果

date +%s
Run Code Online (Sandbox Code Playgroud)

在您的 crontab 中的一个变量中。类似于 TIME=1497950105。现在在您的 crontab 中,您需要一个类似的条目

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

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

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

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

编辑: 我更正了我以前的回答:

  • 你必须用 \ 转义 % 符号,所以%s变成\%s
  • 你必须在命令前加上 /bin/bash -c

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

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

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

编辑2:

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


Per*_*rgk 5

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

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

0 0-23/7 * * * whatever
30 3-23/7 * * * whatever
Run Code Online (Sandbox Code Playgroud)

这是错误的原因是因为 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
Run Code Online (Sandbox Code Playgroud)

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

绝对可以编写一个算法来解决可能出现的情况,但这显然没有多大价值,尤其是考虑到解决方案的实际情况。