CRON时间表达式
CRON时间表达式
我们知道在Linux上的任务计划可以通过cron服务管理,cron服务设置任务运行时间有着自定义的时间表达式,形如
1 | # m h dom mon dow command |
这条记录表示在每周一到周五的08:58自动运行/root/run.sh
脚本,除去command,我们看到时间表达式有m, h, dom, mon, dow
几个部分,分别表示分钟、小时、每月几号、月份、星期几。几号和星期几通常是二选一,指定了一个另一个就会指定成*
表示任意,也可以都指定成*
,则表示每天。
dow
的1-5
表示周一到周五,也可以用逗号分割列举具体星期几,例如1,3,5
表示每周一三五,除了周几,其他时间项也都可以使用此表示法。
除了用-
表示范围,还可以用/
表示频率例如:
1 | # m h dom mon dow command |
表示每周一~周五,小时为9点到14点,从0分开始每5分钟运行一次脚本,这样每天第一次运行的时间是09:00,每天最后一次运行的时间是14:55,中间都是每隔5分钟运行一次。
扩展CRON时间表达式
增加秒
一些程序允许使用扩展的CRON时间表达式,一般会增加秒
的表示
可能通过第一位也可能通过最后一位表示。
即
1 | s m h dom mon dow |
或
1 | m h dom mon dow s |
具体要阅读文档来查询。
增加随机
还有一种扩展是增加随机性
指定,通过以字母H
开头表示
例如
1 | H(55-59) 8 * * 1-5 /root/run.sh |
表示周一到周五,每天[08:55, 09:00)之间的一个随机时间运行/root/run.sh,这样通常是为了缓解多个任务同时启动的压力。
Python中通过带时区的datetime使用croniter
1 | from croniter import croniter |
有时候我们即需要上次触发时间,又需要下次触发时间,要么我们理解了迭代器的方式通过取prev再取next的next,要么我们创建两个cron对象分别取prev和next。
croniter允许通过datetime对象或者timestamp(即time.time()的返回值,float类型)来使用cron对象,但是我们的时间表达式是带有时区概念的,所以cron对象必须明确知道我们的时区,否则将不能正确工作,一种方式是我们使用datetime初始化cron对象,取next或prev的时候也使用datetime类型接收,这时候即使时区不明确也不要紧,但是不能使用timestamp接收next和prev的返回值,否则cron对象会默认使用UTC时区导致返回的float值不正确,如果我们使用带时区的datetime来初始化cron对象则没有这个问题,上面例子就是通过带时区的方式初始化的。
另外,python的cron对象是同时支持秒扩展和随机扩展的,秒放在最后一位,使用随机需要在初始化时指定hash_id,不同的hash_id将影响随机结果,例如我还是上面的例子,但是我需要触发时间不在分钟的整点,而在这一分钟内随机的秒数上,就可以写成下面这样
1 | cron = croniter('0/5 9-14 * * 1-5 H(0-59)', now, hash_id="hash_id") |