linux - 如何安排 Cron 作业在一年中的第 4 周运行

标签 linux shell unix cron

我开发的应用程序使用 native 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) 

我想在一年中第一周的星期一晚上 8 点运行作业,但我不知道如何确定该周的开始时间。 2017 年 12 月 31 日至 2018 年 1 月 6 日是第一周还是 2018 年 1 月 7 日至 1 月 13 日是第一周?

最佳答案

让 cron 作业在特定的周数上运行并不容易 因为一切都取决于你对周数的定义 也用过。

欧洲(ISO 8601)

ISO 8601 standard在世界范围内广泛使用:欧盟和大多数其他国家 欧洲国家、亚洲大部分地区和大洋洲

ISO 8601 标准规定如下:

  • 一周有7天
  • 一周的第一天是星期一
  • 第一周是一年中的第一周 星期四。这意味着这是第一个有 4 天或更多天的星期 一月份。

根据这个定义,周数 53 是可能的。这些发生在一月的第一天 星期五(例如 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

美国或伊斯兰(非 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

注意:这对于您尝试执行的任务来说可能特别麻烦 履行。特别是如果它必须发生在第一个星期一 星期。这个星期一可能不存在。

在 cron 中导入它

无法直接将这些系统添加到 cron。这 周测试应该通过形式的条件测试来完成

weektestcmd weeknr && cmd

对于仅在一年中第 4 周的星期一系统时间 20:00 运行的 cronjob(根据 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

weektestcmd定义为

ISO 8601 周数:

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

美国日历周数:

#!/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 ]]

伊斯兰历周数:

#!/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 ]]

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

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

关于linux - 如何安排 Cron 作业在一年中的第 4 周运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48417100/

相关文章:

c++ - 使用GCC boost 线程编译器错误

regex - 如何从文件中 grep 精确匹配特殊字符?

bash - 通过 bsub 提交时包括 bash 脚本参数

linux - 使用目录下的文件夹名称创建 .finished 文件

linux - 如何为 Linux、OS X、Windows 制作 Travis CI 测试包?

c - evdev如何判断是否移动x11光标?

linux - 我如何在 bash 循环中从文件中分配这些配置变量

linux - 修改字符串以使变量工作

linux - 差异连续行 unix

linux - 在 unix/linux 中格式化日期