crontab定时任务第一次执行任务时间

文章详细解释了Crontab在指定不同时间间隔时的局限性,例如分钟、小时、天和月的范围限制,并通过实例展示了这些限制可能导致的问题。作者提出了一种不那么优雅但可应急使用的解决办法,通过计算当前时间与上次执行时间的差值来实现更精确的定时任务调度。
摘要由CSDN通过智能技术生成

Crontab的使用与局限性
再优秀的工具都有其局限性,在我使用Crontab的过程当中,我发现在指定不同的时间间隔时,Crontab都有其局限性:

minute: 只可以以一个小时为范围来指定间隔多少分钟。
hour: 只可以以一天为范围来指定间隔多少小时。
day-of-month: 只可以以一个月为范围指定间隔多少天。
month: 只可以以一年为范围指定间隔几个月。
我上面的阐述可能不太易于理解,没关系,让我们结合具体实例来讲解:

1、每隔7分钟运行一次命令:
*/7 * * * * /root/bin/check-status.sh
比如说我在今天的10:05分开启了这个定时任务,我的本意是希望这个定时任务是从当前时间开始每隔7分钟执行。但是事实上不是的,crontab的分钟任务是以一个小时为单位和范围的,也就是该任务会在10:07分第一次执行,并每隔7分钟执行一次,待10:56分的这一次执行完成后,下一次并不会在11:03分执行,而是会每隔一小时重新刷新计时,所以下一次会在11:00分执行,再在11:07分执行,以此反复。这就会导致在两个小时的交界处任务的频繁执行,同时,如果我希望任务每隔61分钟执行一次,目前的crontab也无法很好解决。


2、每隔10小时运行一次命令:
0 */10 * * * /root/bin/check-status.sh
比如说我在今天的9:00 am开启了这个定时任务,我的本意是希望这个定时任务是从当前时间开始每隔10小时执行。但事实上不是的,crontab的小时任务是以一天为单位和范围的,也就是该任务会在10:00 am第一次执行,并每隔10小时执行一次。待20:00pm的这一次执行完成后,由于在等待下一次的执行的过程中,时间来到了两天的交界处,因此定时任务会被重新刷新。也就是下一次任务会在第二天的00:00 am时执行,然后再在10:00am执行,以此反复。这就会导致在两天的交界处任务的频繁执行,同时,如果我希望任务每隔25小时执行一次,目前的crontab也无法很好解决。


3、每隔8天运行一次命令:
0 0 */8 * * /root/bin/check-status.sh
比如说我在1月的6日开启了这个定时任务,我的本意是希望这个定时任务是从今日开始每隔8日执行。但事实上不是的,crontab的天任务是以一个月为单位和范围的,同时又由于每个月的起始值是1日,也就是该任务会在9日的零时零分第一次执行,然后在17日、25日的零时零分分别执行一次。再之后就到了两个月的交界处,该定时任务会被重新刷新,也就是下一次任务会在2月1日的零时零分执行,以此反复。这就会导致在两个月的交界处任务的频繁执行,同时,如果我希望任务每隔32天执行一次,目前的crontab也无法很好解决。

4、每隔5个月执行一次命令:
0 0 1 */5 * /root/bin/check-status.sh
比如说我在2020年4月1日开启了这个定时任务,我的本意是希望这个定时任务从本月开始每隔5个月执行。但事实上不是的,crontab的月任务是以一年为单位和范围的,同时又由于每年的起始值是1月,也就是该任务会在6月1日的零时零分第一次执行,然后在11月1日的零时零分执行一次。再之后就到了两年的交界处,该定时任务会被重新刷新,也就是下一次任务会在2021年的1月1日的零时零分执行,以此反复。这就会导致在两年的交界处任务的频繁执行,同时,如果我希望任务每隔13个月执行一次,目前的crontab也无法很好解决。

解决方法
基于以上crontab存在的局限性和我的需求(需指定从当前时刻开始每隔多少时间执行一次任务),我摸索了一阵子之后,得到了一个不太华丽的解决办法,但是可以帮助广大网友们在时间短、任务重的情形之下应急使用。
解决办法同样是在/etc/cron.d/下编写一个定时启动脚本(crontab方面的基础网上都有,请码友们自行补充学习),只是我们的代码略为复杂。脚本内容如下:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
lastRunTime=1611803325
seconds=120

*/1 * * * * root source /etc/profile && intervalRunTime=$[ (`date +\%s` - $lastRunTime) \% $seconds ] && if [( $intervalRunTime -ge 0 ]] && [[ $intervalRunTime -lt 60 ]];then echo $intervalRunTime>>$HOME/crontab.log; fi
1
2
3
4
5
6
7
通过观察以上我编写的代码,大家可以发现我是通过将当前时间绝对秒数作为初始声明变量赋予lastRunTime变量,然后再将间隔时间的秒数(若是间隔2分钟就是120秒,间隔1小时就是3600秒)作为初始声明变量赋予seconds变量。
之后,每隔一分钟定时任务脚本就会判断intervalRunTime(当前时间绝对秒数-lastRunTime)是否大于等于0并且小于60,若满足条件,则echo i n t e r v a l R u n T i m e > > intervalRunTime>>intervalRunTime>>HOME/crontab.log(码友们可以将这部分修改为你们自己需要执行的任务)。
之所以判断条件是大于等于0并且小于60,是因为crontab的最小间隔时间为1分钟,因此将定时任务在每隔seconds后的那一分钟内执行一次。

我的解决办法仍不够优雅,希望码友们如果想到了更好的解决办法或者有什么疑问的话,欢迎在评论区讨论~
————————————————
版权声明:本文为CSDN博主「LebronChen666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_16065939/article/details/113308337

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值