【问题标题】:how to set cronjob for 2 days? [closed]如何设置 cronjob 2 天? [关闭]
【发布时间】:2009-09-05 06:33:25
【问题描述】:

我们想使用 cronjob 来创建数据库备份。

应每两天进行一次备份。可以使用下面的cron-entry吗?

0 0 2 * * * backup-command

如果这是错误的,请告诉我设置 cron 2 天的正确命令。

【问题讨论】:

    标签: cron


    【解决方案1】:

    来自here

    Cron 还支持 'step' 值。

    dom 字段中的 */2 值将 意味着该命令每两天运行一次 同样,*/5 在小时字段中 意味着该命令每 5 次运行一次 小时。例如

    * 12 10-16/2 * * root backup.sh
    

    等同于:

    * 12 10,12,14,16 * * root backup.sh
    

    所以我想你想要0 0 */2 * *

    您所拥有的 (0 0 2 * *) 将在每月 2 日午夜运行该命令。

    附言您的答案似乎有一个额外的星号。格式应为:

    minute hour dom month dow user cmd
    

    因此,您的额外星号将位于 user 字段中。这是故意的吗?

    【讨论】:

    • 一些传说中的实现也包含一个几秒钟的字段,尽管我从未在野外见过。
    • */2 很清楚,但是10-16/2 是什么意思呢?
    【解决方案2】:

    免责声明:这是我的deleted 答案here 的副本。我确实相信这个问题更规范,我的回答更适合这里。

    这个问题有两种解释方式。

    • 我想在每个月的第二天安排一个 cron 作业。
    • 我想每两天安排一次 cron 作业。

    由于一个月有多少天,这是两种完全不同的情况。

    我想在每个月的第二天安排一次 cronjob。

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

    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
      0  0  */2    *  *   command1
      0  0  2-31/2 *  *   command2
      *  *  */2    *  *   command3
    
    • command1 将在每个奇数日的 00:00 执行(步骤 2 的默认范围,即 1,3,5,7,...,31)
    • command2 将在每个偶数日的 00:00 执行(即 2,4,6,8,...,30)
    • command3 是一个经常犯的错误。这将在每个奇数日的每一分钟运行。

    注意:应该理解,在这种方法中command1 将在 1 月 31 日和 2 月 1 日(连续 2 天)运行

    注意:应该理解,在这种方法中,command2 将跳过 1 月 31 日和 2 月 1 日,并且只会在 3 天后运行。

    我想每隔一天安排一次 cronjob(从第 X 天开始)

    这里变得更有趣了。上面的注释已经证明了月份有奇数天的问题。

    快速思考的方法是评估一年中的哪一天:

    % date -d "2018-01-31" '+%j'
    031
    % date -d "2018-02-01" '+%j'
    032
    

    您可以轻松地调查它是奇数还是偶数。但是,这样做时,您在普通年(365 天;闰年有 366 天)的 12 月 31 日和 1 月 1 日再次遇到问题。当您有一个给定日期的连续计数器时,可以解决此问题。输入 UNIX 时间戳,自 1970-01-01 00:00:00 UTC 以来的总秒数。

    % date -d "2018-12-31" '+%s %j'                                                                                                                                                                                                               
    1546214400 365
    % date -d "2019-01-01" '+%s %j' 
    1546300800 001
    % date -d "2019-12-31" '+%s %j'                                                                                                                                                                                                               
    1577750400 365
    % date -d "2020-01-01" '+%s %j'                                                                                                                                                                                                               
    1577836800 001
    

    对于从“2018-03-14”开始每隔一天在00:00command500:00 运行command4 的cronjob,crontab 将如下所示:

    # 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
      0  0  *  *  *   daytestcmd 2 && command4
      0  0  *  *  *   daytestcmd 3 20180314 && command5
    

    daytestcmd 定义为

    #!/usr/bin/env bash
    # get start time in seconds
    start=$(date -d "${2:-@0}" '+%s')
    # get current time in seconds
    now=$(date '+%s')
    # get the amount of days (86400 seconds per day)
    days=$(( (now-start) /86400 ))
    # set the modulo
    modulo=$1
    # do the test
    (( days >= 0 )) && (( days % modulo == 0))
    

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

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

    【讨论】:

    • 不应该是daytestcmd 2daytestcmd 3吗? Shell 函数和脚本不将它们的参数放在括号中。
    • 另一个建议(不过主要是装饰性的):在daytestcmd 中,您可以只使用(( days % modulo == 0 )) 而不是[[ $(( days % modulo )) == 0 ]]
    • @BenjaminW 更新
    【解决方案3】:

    如果你想使用crontab -e 命令,试试这个时间模式:

    0 1 */2 * * command_to_execute
    

    或者,您可以尝试SetCronJob 获取基于网络的解决方案。您可以使用第二个创建行轻松地每 2 天创建一次 cron 作业。

    【讨论】:

    • SetCronJob 没有向我展示易于在我们的本地系统中手动使用的 crontab 格式。我怎样才能找到它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2012-09-30
    相关资源
    最近更新 更多