前言

  因开发需要,所以研究了一番cron表达式,并将内容整理如下:

cron 是什么?

  首先在了解 cron 表达式之前,先谈谈 crontab 定时任务;日常在开发或运维中,经常遇到一些周期性执行的任务或需求,比如说,每个一段时间执行一个脚本,每周一执行一个命令或操作。而 linux 已经给我们提供了一个便捷的方式– crontab 定时任务;crontab 就是一个自定义定时器,我们可以利用 crontab 命令在固定的间隔时间执行指定的系统指令或 shell script 脚本。而这个时间间隔的写法与我们平常用到的cron 表达式相似。作用都是通过利用字符或命令去设置定时周期性地执行一些操作。

  我们可以将cron表达式看作一个以5或6个字符串空格隔开的字符串。这个5或6个空格将字符串划分为6或7个域,每个域代表着不同的含义。默认从左到右为:”秒 分 小时 日 月 星期几 年份“。

cron 内容

域 | 字段 | 含义 | 范围或通配符 | 是否必填
-|-|-|-|-|-|
秒 | Seconds | 秒 | 0-59,-*/| 是
分 | Minutes | 分钟 |0-59,-*/| 是
时 | Hours | 小时 |0-23,-*/ | 是
日 | Day-of-Month | 日期 | 1-31,-*?/LW | 是
月 | Month | 月份 | 1-12 (或 JAN-DEC)或者,- * / | 是
星期 | Day-of-Week | 每星期的周几 | 1-7(或SUNMONTUEWEDTHUFRISAT)或者, - * ? / L # | 是
年 | Year | 年份 | 1970-2099- * /| 否

特殊字符含义:

  • ,:表示列出枚举值。如在月中的值为1,3,则表示一月份和3月份都触发事件。
  • *:表示匹配该域任意值,如小时的字段为*时,表示每一小时都触发事件

  • ?:表示不指定值,用于日期和星期字段之间进行互斥。通常在日期和星期字段中的一个指定值,另外一个用?表示不指定值。个人理解就是忽略该字段的值,直接根据另外一个字段的值进行执行。比如说:日期为2,则星期应为?;

  • -:表示范围,一个连续触发的区间。如:时的值为9-12,则表示9-12小时中的每个小时都触发事件。

  • /:表示间隔时间触发事件(开始时间/时间间隔)。如:在分钟值为0/15,则表示从0分开始,每隔15分钟触发一遍事件。

  • #:表示该月第n个星期x(x#n),仅用星期域。如:星期:6#3,表示该月的第三个星期五。

  • L:表示最后(最后一天或最后一个星期几);仅出现在日和星期的域中。用在日则表示该月的最后一天,用在星期则表示该月的最后一个星期X。如:星期域上的值为5L,则表示该月最后一个星期的星期四。在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果。

  • W:仅用在日的域中,表示距离当月给定日期最近的工作日(周一到周五)。

    如:"4W"表示距离4号最近的工作日(当月的)触发事件;
    (1)当4号就是工作日时,则表示当天触发;当4号为周六时,则表示3号(周五)触发;
    (2)当4号为周日时,则表示在5号(周一)触发;
    再如:"1W"表示距离1号最近的工作日触发事件,但是,该工作日只算当月的。假如当月1号是周六,则”1W“表示在当月3号(周一)触发事件。就算上个月的最后一天是工作日,也不会触发事件。

  • LW‘L’'W'可以一起组合在日字段使用。表示当月的最后一个工作日触发事件。

使用示例

1
2
3
4
5
6
7
8
9
10
11
// 从左往右: 秒 分 时 日 月 星期 年

"30 * * * * ? *" // 表示半分钟触发一次事件
"0 0 12 ? * WED" // 表示每个星期三中午12点
"0 0,15 8-11 * * 2" // 每周一上午8点至11点(8,9,10,11)的第0和第15分钟都触发一次事件
"0 0/5 15 * * ?" // 在每天下午3点到下午3:55期间的每5分钟触发
"0 0 12 L * ?" // 每月最后一日的中午12:00触发事件
"0 0 12 4W * ?" // 每月距离4号最近的工作日的中午12:00触发事件
"0 0 12 LW * ?" // 每月最后一个工作日的中午12:00触发事件
"0 0 12 ? * 6#3" // 每月第3个星期五中午12:00触发事件
"0 11 11 11 11 ? 2019" // 2019年的11月11号 11点11分触发(光棍节)

参考文章