代码之家  ›  专栏  ›  技术社区  ›  ring bearer

如何安排每个月的第一个星期天运行

  •  47
  • ring bearer  · 技术社区  · 14 年前

    我正在用红帽上的Bash。我需要安排一个cron作业在每个月的第一个星期天上午9:00运行。我该怎么做?

    10 回复  |  直到 6 年前
        1
  •  157
  •   Mark Amery    6 年前

    你可以把这样的东西放在盒子里 crontab

    00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script
    

    这个 date +%d

    如果您只在星期天运行此脚本,则意味着它只在一个月的第一个星期天运行。

    你记得吗 date 命令应该转义。

        2
  •  19
  •   Mark Amery    6 年前

    值得注意的是,解决这个问题最明显的方法是

    您可能认为可以编写一个crontab条目,将星期几指定为0(对于星期日),将月份日期指定为1-7,如下所示。。。

    # This does NOT work.
    0 9 1-7 * 0 /path/to/your/script
    

    ... 但是,由于 an eccentricity of how Cron handles crontab lines with both a day-of-week and day-of-month specified 每一个 一个月的星期天。

    这就是为什么您会看到使用 [ ... ] date 设置这样的规则-在crontab中指定星期几并使用 [ date 检查月日是否为<=7运行脚本之前,如 accepted answer ,或在crontab中指定月份范围并使用 [ 日期 要在跑步前检查星期几,请执行以下操作:

    # This DOES work.
    0 9 1-7 * * [ $(date +\%u) = 7 ] && /path/to/your/script
    

    不管 您正在使用它的操作系统:

    • 使用 = ,不是 == ,用于比较。它更具可移植性,因为并非所有shell都使用 支持
    • 使用 %u 说明符到 日期 把一周中的某一天作为一个数字,而不是 %a 接线员,因为 %a 日期 正在磨合。
    • 日期 ,不是 /bin/date /usr/bin/date ,自从 公用设施在不同的系统上有不同的位置。
        3
  •  14
  •   Dirk is no longer here    14 年前

    您需要结合两种方法:

    a) 使用 cron 每个星期天早上9点开始工作。

     00 09 * * 7     /usr/local/bin/once_a_week
    

    b) 年初 once_a_week ,通过shell、Python、C/C++、月计算日期和提取月份。在1到7之间进行测试。如果是的话,执行真正的脚本;如果没有,请安静退出。

        4
  •  6
  •   thesunneversets    14 年前

    黑客解决方案:让cron作业每周日运行一次,但让脚本在开始时检查日期,如果一个月的某一天是>7...

        5
  •  5
  •   Community Egal    7 年前

    0 0 1-7 * * [ "$(date '+\%a')" == "Sun" ] && /usr/local/bin/urscript.sh
    

    但是,

    [ "$(date '+\%a')" == "Sun" ] && echo SUNDAY

    失败 由于在crontab中对“%”进行了特殊处理(对于 https://stackoverflow.com/a/3242169/2919695

        6
  •  5
  •   MGP    8 年前

    运行cron任务第一个星期一,第三个星期二,上星期天,任何。。

    http://xr09.github.io/cron-last-sunday/

    把枪放好 run-if-today 在路径中编写脚本并与cron一起使用。

    30 6 * * 6 root run-if-today 1 Sat && /root/myfirstsaturdaybackup.sh
    

    这个 如果日期正确,脚本将只返回0(bash值为True)。

    编辑:

    # run every first saturday
    30 6 * * 6 root run-if-today 1 && /root/myfirstsaturdaybackup.sh
    
    # run every last sunday
    30 6 * * 7 root run-if-today L && /root/lastsunday.sh
    
        7
  •  0
  •   gtrak    14 年前

    可以使用cron.hourly调用另一个脚本。然后,该脚本将检查是否是本月的第一个星期日和上午9点,如果是,运行您的程序。对我来说已经足够完美了:-)。

        8
  •  0
  •   user390948    14 年前

    然后把包装纸安排在下个月的第一个星期天。在那之后,它会自己处理一切。

    代码应该是这样的(强调某些东西…没有错误检查完成):

    #! /bin/bash
    #We run your code first
    /path/to/your/code
    #now we find the next day we want to run
    nskip=28 #the number of days we want to check into the future
    curr_month=`date +"%m"`
    new_month=`date --date='$nskip days' +"%m"`
    if [[ curr_month = new_month ]] 
    then
    ((nskip+=7))
    fi
    date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler
    #schedule the job using "at"
    at -m $date < /path/to/wrapper/code
    

    找到下一个第一个星期天的逻辑很简单。因为我们是从本月的第一个星期天开始的,所以加上28个星期天,我们要么是本月的最后一个星期天,要么是下个月的第一个星期天。如果是本月,我们增加到下个星期天(下个月的第一周)。

    我用了“at”。我不知道那是不是作弊。不过,主要的想法是找到下一个第一个星期天。在那之后,您可以替换任何您想要的调度程序,因为您知道运行作业的日期和时间(不过,不同的调度程序可能需要不同的日期语法)。

        9
  •  -1
  •   Anup    9 年前
        10
  •  -3
  •   Nicola Iannello    11 年前

    00 09 1-7*0/usr/local/bin/每周一次

    每月前7天的每个星期日