定时任务crontab
1. crontab循环执行定时任务
1.1 crond服务管理与控制访问
crontab命令是需要crond服务支持的,crond服务同样是独立的服务。 crond服务默认是自启动的。
[root@centos2 ~]# systemctl status crond ● crond.service - Command Scheduler Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled) Active: active (running) since 三 2019-11-13 16:24:18 CST; 2h 24min ago Main PID: 1267 (crond) Tasks: 1 CGroup: /system.slice/crond.service └─1267 /usr/sbin/crond -n 11月 13 16:24:18 centos2 systemd[1]: Started Command Scheduler. 11月 13 16:24:19 centos2 crond[1267]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 17% if used.) 11月 13 16:24:19 centos2 crond[1267]: (CRON) INFO (running with inotify support)
crontab命令和at命令类似,也是通过/etc/cron.allow和/etc/cron.deny文件来限制某些用户是否可以使用crontab命令的,原则也非常相似
当系统中有/etc/cron.allow文件时,只有希尔此文件的用户可以使用crontab命令,没有写入的用户不能使用crontab命令。同样如果有此文件,/etc/cron.deny文件会被忽略,/etc/cron.allow文件的优先级更高
当系统中只有/etc/cron.deny文件时,则写入此文件的用户不能使用crontab命令,没有写入文件的用户可以使用crontab命令
这个规则基本和at的规则一直,同样/etc/cron.allow文件的优先级比/etc/cron.deny文件的优先级高,Linux中默认只有/etc/cron.deny文件。
1.2 用户的crontab设置
每个用户都可以实现自己的crontab定时任务,只要是使用这个用户身份执行“crontab -e”命令即可,当然这个用户不能加入/etc/cron.deny文件中
[root@centos2 ~]# crontab [选项] 选项: -e:编辑crontab定时任务 -l:查询crontab任务 -r:删除当前用户所有的crontab任务,如果有多个任务,只想删除一个,可以使用“crontab -e” -u 用户名:修改或删除其他用户的crontab任务。只有root使用
[root@centos2 ~]# crontab -e
#crontab编辑界面。会打开vim编辑
* * * * * 执行的任务
项目 | 含义 | 范围 |
第一个“*” | 几分 | 0-59 |
第二个“*” | 几点 | 0-23 |
第三个“*” | 一个月第几天 | 1-31 |
第四个“*” | 几月 | 1-12 |
第五个“*” | 星期几 | 0-7(0和7都代表星期日) |
在时间表示时,还有一些特殊符号
特殊符号 | 含义 |
* | 代表任何时间。比如第一个“*”就表示一小时中每分钟都执行一次的意思 |
, | 代表不连续的时间。比如“0 8,12,16 * * * 命令”,就代表每天的8点0分,12点0分,16点0分都执行一次命令 |
- | 代表连续的时间范围。比如“0 5 * * 1-6 命令”,代表在周一至周六的凌晨5点0分执行命令 |
*/n | 代表每隔多久执行一次。比如“*/10 * * * * 命令”,代表每隔10分钟就执行一遍命令 |
例
10 2 * * * 命令 每天凌晨2点10分执行命令 10 2 * * 7 命令 每周日凌晨2点10分执行命令 10 2 1,15 * * 命令 每月1号15号的凌晨2点10分执行命令 10 2 * * 1-6 命令 每周一至周六的凌晨2点10分执行命令 */10 2 * * * 命令 每天凌晨2点,每隔10分钟执行一次命令 10 2 1,15 * 1 命令 每月1号15号,每周一的2点10分执行命令。注意:最好星期几和几号不要同时出现,因为定义的都是天。容易混乱
[root@centos2 ~]# crontab -e #进入编辑界面 */5 * * * * echo "123" >> /root/test.log [root@centos2 ~]# crontab -l */5 * * * * echo "123" >> /root/test.log #查看root用户的crontab任务 [root@centos2 ~]# crontab -r #删除root用户所有的定时任务,果只想删除某一个定时任务,可以“crontab -e”进入编辑模式手工删除
1.3 crontab的注意事项
留个选项都不能为空,必须填写。不确定就使用"*"代表任意时间
crontab定时任务,最小有效时间是分钟,最大时间范围是月。
在定义时间时,日期和星期最好不要在一条定时任务中出现,他们都是以天做单位,容易让管理员混乱
在定时任务中,不管是直接写命令,还是在脚本中写命令,最好有绝对路径。使用相对路径有时会报错
使用定时任务执行shell脚本时,注意环境变量继承问题。
1.4 系统的crontab设置
“crontab -e”是每个用户执行的命令,也就是说不同的用户身份可以执行自己的定时任务。有些定时任务需要系统执行,这时需要编辑/etc/crontab这个配置文件。当然,并不是说写入/etc/crontab配置文件中的定时任务执行时,不需要用户身份,而是“crontab -e”命令定义定时任务时,默认用户身份是当前登录用户。而修改/etc/crontab配置文件时,定时任务的执行着身份是可以手工指定的。这样定时任务的执行会更加灵活,修改起来也更加方便。
SHELL=/bin/bash #标示使用哪种shell PATH=/sbin:/bin:/usr/sbin:/usr/bin #指定PATH环境变量,crontab是使用自己的PATH,而不是用系统默认的,所以在定时任务中出现的命令最好使用大写 MAILTO=root #如果有报错输出,或命令结果又输出,会向root发信息 # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed # 分 时 日 月 周 执行者身份 命令
2. anacron
anacron是用来干什么的呢?我们的Linux服务器如果不是24小时开机的,那么刚好在关机的时间段之内有系统定时任务(cron)需要执行,那么这些定时任务是不会执行的。也就是说,假设我们需要在凌晨5点05分执行系统的日志备份,但是我们的Linux服务器不是24小时开机的,在晚上需要关机,白天上班之后才会再次开机。这个定时任务的执行时间我们的服务器刚好没有开机,那么这个任务就不会执行了。anacron就是用来解决这个问题的。
anacron会使用一天,七天,一个月作为检测周期,用来判断是否有定时任务在关机之后没有执行,如果有这样的任务,anacron会在特定的时间重新执行这些定时任务。那么anacron是如何判断这些定时任务已经超过了执行时间呢?在系统的/var/spool/anacron/目录中存在cron.{daily,weekly,monthly}文件,这些文件中都保存着anacron上次执行时的时间。anacron会去读取这些文件中的时间,然后和当前时间做比较,若果两个时间的差值超过了anacron的指定时间差值(一般是1天,7天和一个月),就说明有定时任务漏掉了没有被执行,这时anacron会介入而执行这个漏掉的定时任务,从而保证在关机时没有被执行的定时任务不会被漏掉。
[root@centos2 ~]# anacron [选项] [工作名] 选项 -s:开始anacron工作,依据/etc/anacrontab文件中的设定的延迟时间执行 -n:立即执行/etc/anacrontab中所有的工作,忽略所有的延迟时间 -u:更新/var/spool/anacron/cron.{daily,weekly,monthly}文件中的时间戳,但不执行任何工作 参数: 工作名:是依据/etc/anacrontab文件中定义的工作名
在我们当前的Li nux中,其实不需要执行任何anacron命令,只需要配置好/etc/anacrontab文件,系统就会依赖这个文件中的设定来通过anacron执行定时任务。那么关键就是/etc/anacrontab文件的内容。
# /etc/anacrontab: configuration file for anacron # See anacron(8) and anacrontab(5) for details. SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root #前面的内容和/etc/crontab类似 # the maximal random delay added to the base delay of the jobs RANDOM_DELAY=45 #最大随机延迟 # the jobs will be started during the following hours only START_HOURS_RANGE=3-22 #anacron的执行时间范围是3:00-22:00 #period in days delay in minutes job-identifier command 1 5 cron.daily nice run-parts /etc/cron.daily 7 25 cron.weekly nice run-parts /etc/cron.weekly @monthly 45 cron.monthly nice run-parts /etc/cron.monthly
#天数 强制延迟(分) 工作名称 实际执行的命令
#时间差超过天数时,强制延迟多少分钟之后,就执行命令
这个文件中“RANDOM_DELAY”定义的是最大随机延迟,也就是说cron.daily任务如果超过1天没有执行,并不会马上执行,而是先延迟强制延迟时间之后,再延迟随机延迟时间之后再执行命令。“START_HOURS_RANGE”定义anacron的执行时间范围,anacron只会在这个时间范围之内执行。
我们用cron.daily工作来说明下/etc/anacrontab的执行过程:
首先读取/var/spool/anacron/cron.daily中的上一次anacron执行的时间
和当前时间比较,如果两个时间的差值超过1天,就执行cron.daily工作
执行这个工作只能在03:00-22:00之间
执行工作时强制延迟时间为5分钟,再随机延迟0-45分钟时间
使用nice命令指定默认优先级,使用run- parts脚本执行/etc/cron.daily目录中的所有可执行文件
我们只需要把需要定时执行的脚本放入/etc/cron.{daily,weekly,monthly}目录当中,就会每天、每周或每月执行
我们如果做修改的话,只用修改/etc/anacrontab配置文件即可
[root@centos2 ~]# vim /etc/anacrontab # /etc/anacrontab: configuration file for anacron # See anacron(8) and anacrontab(5) for details. SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # the maximal random delay added to the base delay of the jobs RANDOM_DELAY=0 #随机延迟改为0分钟,不再随机延迟 # the jobs will be started during the following hours only START_HOURS_RANGE=3-5 #执行时间范围为3:00-5:00 #period in days delay in minutes job-identifier command 1 0 cron.daily nice run-parts /etc/cron.daily 7 0 cron.weekly nice run-parts /etc/cron.weekly @monthly 0 cron.monthly nice run-parts /etc/cron.monthly #强制延迟也改为0分钟,不再强制延迟
这样我们所有放入/etc/cron.{daily,weekly,monthly}目录中的脚本都会在指定时间运行了,而且也不怕服务器万一关机的情况了