该模块为类似 cron 的任务调度提供了一个易于使用的界面。
项目描述
该模块为类似 cron 的任务调度提供了一个易于使用的界面。该库实现的 cron 表达式求值与 Vixie Cron 100% 兼容,还支持Java Quartz 的 非标准“L”、“W”和“#”字符。
该库提供的另一个有用功能是能够以任意间隔设置触发器,例如每 9 小时、每 11 分钟等,而不会出现使用星号斜线表示法引起的问题;在大多数 cron 实现的小时字段中使用 */9将导致触发器在每天下午 6:XX 的上午 9:XX 触发,但使用 CronExpresssions,触发器将在上午 9:XX 和下午 6:XX 触发, 第二天 3:XX AM, 12:XX PM, 9:XX PM 等等。
例子
标准 Cron 字段
此示例显示 CronExpression 的基本实例化以及如何检查触发器是否应在给定时间触发。时间元组按顺序由年、月、日、小时和分钟组成。
>>> job = CronExpression("0 0 * * 1-5/2 find /var/log -delete")
>>> job.check_trigger((2010, 11, 17, 0, 0))
True
>>> job.check_trigger((2012, 12, 21, 0 , 0))
False
周期性触发
此触发器提醒您从 2010 年 5 月 1 日上午 7 点(格林威治标准时间 -6:00)开始每 9 小时喂一次小猫。
>>> job = CronExpression("0 %9 * * * Feed kitten", (2010, 5, 1, 7, 0, -6))
>>> job.comment
"Feed kitten"
>>> job.check_trigger((2010, 5, 1, 7, 0), utc_offset=-6)
True
>>> job.check_trigger((2010, 5, 1, 16, 0), utc_offset=-6)
True
>>> job.check_trigger((2010, 5, 2, 1, 0), utc_offset=-6)
True
不到十行的简单 cron 调度程序
使用 CronExpressions,只需几行代码就可以创建一个非常基本的任务调度程序。
import time
import os
import cronex
while True:
for line in open("crontab"):
job = cronex.CronExpression(line.strip())
if job.check_trigger(time.gmtime(time.time())[:5]):
os.system("(" + job.comment + ") & disown")
time.sleep(60)
表达式语法
已经熟悉 cron 的读者应该跳到标题为Repeaters的部分。除了中继器之外,与 Vixie Cron 的 cron 表达式评估实现的唯一其他显着区别是范围环绕:小时字段中的 22-2 与22,23,0,1,2相同。其他一切都是标准的 man 5 crontab。
每个 cron 触发器都由五个空格分隔的字段组合指定,这些字段指示事件何时发生。按顺序,这些字段指定一小时后的分钟、一天中的小时、月中的某天、月和一周中的某天的触发时间。
.--------------- minute (0 - 59) | .------------ hour (0 - 23) | | .--------- day of month (1 - 31) | | | .------ month (1 - 12) or Jan, Feb ... Dec | | | | .---- day of week (0 - 6) or Sun(0 or 7), Mon(1) ... Sat(6) V V V V V * * * * * command to be executed / trigger comment
有四种方法可以为每个字段指定有效值,所有这些方法都可以使用逗号相互组合。有范围、通配符、步骤和中继器。中继器是对 cron 表达式的非标准补充,允许指定具有任意周期的事件。
如果给定时间段的小时、分钟和月份是触发器中指定的有效值,并且月份中的某天或星期几是有效值,则触发器会触发。
范围和通配符
范围指定开始和结束时间段。它包括从起始值到结束值的所有值。
字段中用“*”表示的通配符代表所有有效值。这与在分钟字段中指定范围 0-59、在小时中指定范围 0-23、在天中指定范围 1-31、在月份中指定范围 1-12 以及在工作日中指定范围几乎相同。
从 6 月到 9 月,每天中午都会触发以下 cron 表达式:
0 12 * 6-9 * * remind "Walk the ducks"
如果星期几字段是通配符,但月份的日期是一个明确的范围,星期几将被忽略,触发器只会在月份的指定日期被激活。如果月份中的日期是通配符,则适用相同的原则。
此表达式在每周日下午 4:00 触发:0 16 * * 1-5
这个是每月前九天触发的:0 16 1-9 * *
第一周每天都会触发这个,但之后的星期六才会触发:0 16 1-7 * 6
脚步
步骤由“/”和范围或通配符后面的数字指定。使用步长遍历范围时,每次都会跳过指定数量的值。1-10/2的功能等同于1,3,5,7,9。
以下 cron 表达式在每个季度的第一天(1 月、4 月、... 10 月)午夜触发:
0 0 1 */2 * * delete log.txt
中继器
中继器使事件在从给定时刻开始的任意时间段后触发,该时刻至今被称为纪元。默认情况下,纪元是 1970 年 1 月 1 日 0:00。不同字段中的触发器彼此独立运行:%10 %10 * * *将在 00:00、00:10、... 00:50、10:00、10:10 等触发...
以下 cron 表达式每 5 个月在 10 日中午触发:
0 12 10 %5 * Something amazing happens at noon...
特殊符号
还有三个额外的特殊符号:“L”、“W”和“#”。
在月份字段中使用时,后跟“L”的数字表示出现由“L”前面的值表示的星期几。在日期字段中,不带前缀整数的“L”表示该月的最后一天。0 0 * * 5L表示每个月最后一个星期五的午夜触发器,而0 0 L 2 * 表示每年二月最后一天的午夜触发器。
“W”仅对表示月份的天数的字段有效,并且必须以整数作为前缀。它指定最接近给定日期的工作日(周一至周五)。在构造0 0 7W * *中,当 7 号落在星期六时,触发器将在 6 号激活。如果 7 日是星期日,则触发器将在 8 日激活。
“#”仅对表示星期几的字段有效。“#”有一个前缀和后缀,分别代表星期几和星期几的第 N 次出现。0 0 * * 0#5将在每个第 5 个星期日触发。
各种各样的
上面的所有结构都可以使用逗号组合在单个字段中:0,30 */7,5 1,%90,L 9-4/6,5-8 4#2是一个完全有效的表达式,尽管它很可怕.
除了上面的原子之外,还有几个特殊的字符串可以替代常见的 cron 表达式。这些字符串替换,而不是增加 cron 字段。
String Equivalent ------ ---------- @yearly 0 0 1 1 * @annually 0 0 1 1 * @monthly 0 0 1 * * @weekly 0 0 * * 0 @daily 0 0 * * * @midnight 0 0 * * * @hourly 0 * * * *