如何安排一个Cron工作运行一年中的第四周

use*_*954 3 unix linux shell cron

我使用的是一个使用本机Unix CRON选项卡来安排作业的应用程序.参数说明如下:

Minute, Hour, Da_of_Week(1-7, 1=Sun), Day_of_Month(1-31), Day_of_Year(1-365), Week (1-52), Month (1-12) 
Run Code Online (Sandbox Code Playgroud)

我想在一周的第一周的晚上8点开始工作,但我不知道如何确定一周的开始时间.2017年12月31日 - 2018年1月6日第一周或第一周的1月7日或1月7日是第一周?

kva*_*our 5

让cron作业在特定的周数上运行并不容易,因为一切都取决于您使用的周数的定义.

欧洲(ISO 8601)

ISO 8601标准被广泛应用于世界:欧盟和大多数欧洲国家,亚洲大部分地区和大洋洲

ISO 8601标准规定如下:

  • 一周有7天
  • 一周的第一天是星期一
  • 第一周是包含星期四的一年中的第一周 .这意味着它是1月份的第一周,持续4天或更长时间.

根据这个定义,可能有一个星期数53.这些发生在1月1日是星期五(例如2016-01-01,2010-01-01).或者,如果前一年是闰年,也是星期六.(例如2005-01-01)

   December 2015               January 2016        
 Mo Tu We Th Fr Sa Su CW    Mo Tu We Th Fr Sa Su CW
     1  2  3  4  5  6 49                 1  2  3 53
  7  8  9 10 11 12 13 50     4  5  6  7  8  9 10 01
 14 15 16 17 18 19 20 51    11 12 13 14 15 16 17 02
 21 22 23 24 25 26 27 52    18 19 20 21 22 23 24 03
 28 29 30 31          53    25 26 27 28 29 30 31 04
Run Code Online (Sandbox Code Playgroud)

美国或伊斯兰(不是ISO 8601)

并非所有国家/地区都使用ISO 8601系统.他们使用更绝对的方法.美国系统用于加拿大,美国,新西兰,印度,日本......伊斯兰教系统通常用于中东地区.两个系统都非常相似.

美国:

  • 一周有7天
  • 一周的第一天是星期天
  • 第一周从1月1日开始

伊斯兰:

  • 一周有7天
  • 一周的第一天是星期六
  • 第一周从1月1日开始

根据这些定义,可能在一年的开始和结束时有部分周.因此,一年中的第一周和最后一周不能包含所有工作日.

American:

    December 2015                January 2016       
 Su Mo Tu We Th Fr Sa CW     Su Mo Tu We Th Fr Sa CW
        1  2  3  4  5 49                     1  2 01
  6  7  8  9 10 11 12 50      3  4  5  6  7  8  9 02
 13 14 15 16 17 18 19 51     10 11 12 13 14 15 16 03
 20 21 22 23 24 25 26 52     17 18 19 20 21 22 23 04
 27 28 29 30 31       53     24 25 26 27 28 29 30 05
                             31                   06

Islamic:

   December 2015                 January 2016       
 Sa Su Mo Tu We Th Fr CW     Sa Su Mo Tu We Th Fr CW
           1  2  3  4 49                        1 01
  5  6  7  8  9 10 11 50      2  3  4  5  6  7  8 02
 12 13 14 15 16 17 18 51      9 10 11 12 13 14 15 03
 19 20 21 22 23 24 25 52     16 17 18 19 20 21 22 04
 26 27 28 29 30 31    53     23 24 25 26 27 28 29 05
                             30 31                06
Run Code Online (Sandbox Code Playgroud)

注意:对于您尝试执行的任务,这可能特别麻烦.特别是如果必须在第一周的星期一发生.本周一可能不存在.

在cron中导入它

将这些系统添加到cron不能以直接方式完成.周测试应该通过表格的条件测试来完成

weektestcmd weeknr && cmd
Run Code Online (Sandbox Code Playgroud)

对于cronjob仅在系统时间20:00系统时间的第4周的星期一运行(如OP请求的那样),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 20  *  *  1   weektestcmd 4 && cmd
Run Code Online (Sandbox Code Playgroud)

随着weektestcmd定义为

ISO 8601周数:

#!/usr/bin/env bash
[[ $(date '+%V') -eq $1 ]]
Run Code Online (Sandbox Code Playgroud)

美国日历周数:

#!/usr/bin/env bash
# obtain the day of year
doy=$(date "+%j")
# compute the week offset of the first of January
## compute the day of the week with Mo=1 .. Su=7
offset=$(date -d $(date "+%Y")-01-01 "+%u")
## Take the modulo for the offset as Su=0
offset=$(( offset%7 ))
# Compute the current week number
cw=$(( (doy + offset + 6)/7 ))
[[ $cw -eq $1 ]]
Run Code Online (Sandbox Code Playgroud)

伊斯兰历法周数:

#!/usr/bin/env bash
# obtain the day of year
doy=$(date "+%j")
# compute the week offset of the first of January
## compute the day of the week with Mo=1 .. Su=7
offset=$(date -d $(date "+%Y")-01-01 "+%u")
## Take the modulo for the offset as Sa=0
offset=$(( (offset + 1)%7 ))
# Compute the current week number
cw=$(( (doy + offset + 6)/7 ))
[[ $cw -eq $1 ]]
Run Code Online (Sandbox Code Playgroud)

注意:请注意,在美国和伊斯兰教系统中,可能在第1周没有星期一.

注意:还有其他定义周数的方法.尽管如此,方法保持不变.定义一个脚本,用于检查周数并在cron中使用它.