crontab和cron表达式详解

我们在定时任务中经常能接触到cron表达式,但是在写cron表达式的时候我们会遇到各种各样版本的cron表达式,比如我遇到过5位、6位甚至7位的cron表达式,导致我一度搞混这些表达式。更严重的是,当我们没有准确写出cron表达式时,会出现定时任务一直没有执行,或者定时任务执行太频繁的糟糕情况。

其实,这里的cron表达式是广义的,它包括了狭义的cron表达式和crontab表达式。

cron表达式

Cron表达式是一个字符串,字符串以5或6个空格隔开, 分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
(1) Seconds Minutes Hours DayofMonth Month DayofWeek Year
(2) Seconds Minutes Hours DayofMonth Month DayofWeek

域 允许的数值 允许的特殊字符 备注 秒 0~59 – * / – 分 0~59 – * / – 小时 0~23 – * / – 日期 1~31 – * ? / L W C – 月份 1~12 JAN-DEC – * / – 星期 1~7 SUN-SAT – * ? / L C # 1 表示星期天,2 表示星期一,依次类推 年(可选) 留空,1970~2099 , – * / 自动生成,工具不显示该值

字符 含义 示例 * 表示匹配域的任意值 在分这个域使用

这意味着该事件每分钟都会被触发?表示匹配字段的任意值,但

[En]

Which means that the event is triggered every minute ? Represents any value of the matching field, but

由于这两个域名在每个月的20日都会互相影响触发计划,所以无论是在每个月的20日是哪一天,都只能使用如下方式:

[En]

Because the two domains affect each other To trigger the schedule on the 20th of each month, no matter what day it is on the 20th of each month, you can only use the following:

。其中,由于日期字段已在20日指定,因此只能使用上周字段

[En]

. Among them, because the date field has been specified on the 20th, the last week field can only be used

,不能使用

。如果最后一位使用

,则表示不管星期几都会触发,与日期域的 20 号相斥,此时表达式不正确。 – 表示起止范围 在分这个域使用 5-20,表示从 5 分到 20 分钟每分钟触发一次。 / 表示起始时间开始触发,然后每隔固定时间触发一次 在分这个域使用 5/20,表示在第 5 分钟触发一次,之后每 20 分钟触发一次,即 5、 25、45 等分别触发一次。 , 表示列出枚举值 在分这个域使用 5,20,则意味着在 5 和 20 分每分钟触发一次。 L 表示最后,只能出现在日和星期两个域 在星期这个域使用 5L,意味着在最后的一个星期四触发。 W 表示有效工作日(周一到周五),只能出现在日这个域,系统将在离指定日期最近的有效工作日触发事件。 在日这个域使用 5W,如果 5 号是星期六,则将在最近的工作日星期五,即 4 号触发。如果 5 号是星期天,则在 6 号(周一)触发;如果 5 号为工作日,则就在 5 号触发。另外,W 的最近寻找不会跨过月份。 LW 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 # 表示每个月第几个星期几,

在星期这个域使用 4#2,表示某月的第二个星期三,4 表示星期三,2 表示第二个。

  • */5 * * * * ?:每隔 5 秒执行一次
  • 0 */1 * * * ?:每隔 1 分钟执行一次
  • 0 0 2 1 * ? *:每月 1 日的凌晨 2 点执行一次
  • 0 15 10 ? * MON-FRI:周一到周五每天上午 10:15 执行作业
  • 0 15 10 ? 6L 2002-2006:2002 年至 2006 年的每个月的最后一个星期五上午 10:15 执行作业
  • 0 0 23 * * ?:每天 23 点执行一次
  • 0 0 1 * * ?:每天凌晨 1 点执行一次
  • 0 0 1 1 * ?:每月 1 日凌晨 1 点执行一次
  • 0 0 23 L * ?:每月最后一天 23 点执行一次
  • 0 0 1 ? * L:每周星期天凌晨 1 点执行一次
  • 0 26,29,33 * * * ?:在 26 分、29 分、33 分执行一次
  • 0 0 0,13,18,21 * * ?:每天的 0 点、13 点、18 点、21 点都执行一次
  • 0 0 10,14,16 * * ?:每天上午 10 点,下午 2 点,4 点执行一次
  • 0 0/30 9-17 * * ?:朝九晚五工作时间内每半小时执行一次
  • 0 0 12 ? * WED:每个星期三中午 12 点执行一次
  • 0 0 12 * * ?:每天中午 12 点触发
  • 0 15 10 ? * *:每天上午 10:15 触发
  • 0 15 10 * * ?:每天上午 10:15 触发
  • 0 15 10 * * ? *:每天上午 10:15 触发
  • 0 15 10 * * ? 2005:2005 年的每天上午 10:15 触发
  • 0 * 14 * * ?:每天下午 2 点到 2:59 期间的每 1 分钟触发
  • 0 0/5 14 * * ?:每天下午 2 点到 2:55 期间的每 5 分钟触发
  • 0 0/5 14,18 * * ?:每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发
  • 0 0-5 14 * * ?:每天下午 2 点到 2:05 期间的每 1 分钟触发
  • 0 10,44 14 ? 3 WED:每年三月的星期三的下午 2:10 和 2:44 触发
  • 0 15 10 ? * MON-FRI:周一至周五的上午 10:15 触发
  • 0 15 10 15 * ?:每月 15 日上午 10:15 触发
  • 0 15 10 L * ?:每月最后一日的上午 10:15 触发
  • 0 15 10 ? * 6L:每月的最后一个星期五上午 10:15 触发
  • 0 15 10 ? * 6L 2002-2005:2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发
  • 0 15 10 ? * 6#3:每月的第三个星期五上午 10:15 触发

Crontab表达式

Crontab表达式还是比较好区分的,它 只有五位

crontab指令常见于Unix和类Unix的操作系统之中,用于设置周期性被履行的指令。该指令从规范输入设备读取指令,并将其存放于”crontab”文件中,以供之后读取和履行。

crontab贮存的指令被看护进程激活,crond常常在后台运转,每一分钟检查是否有预订的作业需求执行。

crontab表达式的每一行均严格遵守特定的表达式,由空格或tab分隔为数个领域,每个领域可以放置单一或多个表达式。

时程表的格式:z1 z2 z3 z4 z5 program,其中 z1 是分钟,z2 小时,z3 一个月份中的第几日,z4 月份,z5 表示一个星期中的第几天。program 表示要执行的shell或者命名。

0    2    *    *    6
*    *    *    *    *    *
-    -    -    -    -    -
|    |    |    |    |    |
|    |    |    |    |    + 年 [可选参数]
|    |    |    |    +----- 星期几 (0 - 7) (Sunday=0 or 7)
|    |    |    +---------- 月份 (1 - 12)
|    |    +--------------- 几号 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)

cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务。

cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明: crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数;crontab -l //列出某个用户cron服务的详细内容;crontab -r //删除某个用户的cron服务;crontab -e //编辑某个用户的cron服务。

  • 30 16 * * * /usr/local/etc/rc.d/lighttpd restart 表示每晚天中午的16:30重启lighttpd
  • 40 3 3,15,23 * * /usr/local/etc/rc.d/lighttpd restart 表示每月3、15、23日的3 : 40重启lighttpd
  • 30 3 * * 6,0 /usr/local/etc/rc.d/lighttpd restart 表示每周六、周日的3 : 30重启lighttpd
  • 0,30 20-22 * * * /usr/local/etc/rc.d/lighttpd restart 表示在每天20 : 00至22 : 00之间每隔30分钟重启lighttpd
  • 0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart 表示每星期六的11 : 00 pm重启lighttpd
  • 0 */2 * * * /usr/local/etc/rc.d/lighttpd restart 每2小时重启lighttpd
  • * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart 晚上11点到早上7点之间,每隔一小时重启lighttpd
  • 0 11 5 * mon-wed /usr/local/etc/rc.d/lighttpd restart 每月的5号与每周一到周三的11点重启lighttpd
  • 0 5 1 jan * /usr/local/etc/rc.d/lighttpd restart 一月一号的5点重启lighttpd

时区问题

在github的action中使用crontab表达式设置定时任务时,通常会出现这样一个问题,我设置的是北京时间的每天8:00执行任务,结果在凌晨就执行了。

这个问题出现的原因是,crontab表达式的时间是受操作系统所设置的时区影响的,而如果在github action中使用ubuntu环境运行定时任务,里面的时区默认使用的是UTC,UTC时间比北京时间提前8小时。例如北京时间每天8:00调度函数,那么转化为UTC时间就是每天0:00调度函数,则可以使用 0 0 0 * * *,而如果你想在北京时间每天20:00指定定时任务,则需要转换为UTC时间的12:00,cron表达式可以表示为: 0 0 12 * * *

Original: https://www.cnblogs.com/GarrettWale/p/16256688.html
Author: Garrett_Wale
Title: crontab和cron表达式详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/523654/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球