工作原理:
/etc/crontab里的任务因为一些原因(比如关机情况)错过执行时间,那么该任务只能下次执行,为了避免少了这一次执行,可以将这个任务放在/etc/anacrontab里。在开机启动时候或者crontab里定时里执行anacron -s命令,这时候,会检查/var/spool/anacrontab/job-identifier里记录的时间,如果当前时间和这里记录的时间超过了/etc/anacrontab里的该任务设置,那么就会在"随机时间+delay时间"时刻执行/etc/anacrontab里该任务后跟的命令,这个命令和/etc/crontab里的命令是一样的。因此,这个anacrontab是crontab的一个补充,它的日志和crontab日志一样,记录在/var/log/cron中。其次,它只是一个进程,在确定随机执行时间后,该进程就一直锁住该任务。整个流程总结一下就是:触发->检查->确定时间执行。
通常情况下,一般搭配run-parts使用。当执行/etc/crontab里的任务时候,会由run-parts执行该目录下的所有脚本,在该目录下会存放一个按文件名排序第1的oanacron脚本,该脚本内容大体是"anacron -u"命令,该脚本的作用是更新/var/spool/anacrontab/job-identifier的时间,这个时间是以天为单位,因此anacrontab使用的是/etc/crontab里最小间隔为天的任务。该文件的内容形式如YYYYMMDD,这种形式记录。当run-parts执行目录里的脚本时候,会第1个执行oanacron脚本。
当开机或者crontab里写入了anacron -s命令时候,会触发anacrontab检查/etc/anacrontab里的任务的记录时间和当前时间的差值,如果满足了设置,那么就会触发anacron去执行。
anacron执行的时间有delay设置和随机时间决定,会在日志里显示。
时间间隔的检查只要相减满足就可以。然后就更新成当前时间。如果说你的任务间隔不是超过1天,那么这个就不适用了。
操作:
1、编写/etc/crontab,添加一条,在每天21:10执行目录下的所有脚本
vim /etc/crontab
10 21 * * * root run-parts /tmp/test_sh
2、创建目录里的脚本文件并赋予权限
cd /tmp/test_sh
vim 0anacron
#!/bin/bash
if [ ! -e /var/run/anacron.pid ]; then
anacron -u cron.test
fi
[root@centos6 ~]# ls -l /tmp/test_sh
total 20
-rwxr-xr-x. 1 root root 75 Sep 2 17:33 0anacron
-rw-r--r--. 1 root root 64 Sep 2 17:34 1.log
-rwxrwxrwx. 1 root root 49 Sep 2 11:25 1.sh
-rw-r--r--. 1 root root 64 Sep 2 17:34 2.log
-rwxrwxrwx. 1 root root 48 Sep 2 11:26 2.sh
[root@centos6 ~]#
3、修改/etc/anacrontab,定义该job的名称为"cron.test",检查时间间隔为超过1天(不管是早1天还是晚1天),执行job的时间段为3点-22点,执行时间为随机2分钟+延迟1分钟后执行。
vim /etc/anacrontab
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=2
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#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
1 1 cron.test nice run-parts /tmp/test_sh
4、修改当前系统时间和设定时间差异1天,手动触发
修改系统时间为3-22点范围内
[root@centos6 ~]# date -s "20220909 08:00:00"
Fri Sep 9 08:00:00 CST 2022
[root@centos6 ~]#
[root@centos6 ~]# cat /var/spool/anacron/cron.test
20220907
[root@centos6 ~]#
[root@centos6 ~]# anacron -s cron.test
[root@centos6 ~]#
从下面的日志中可以看出,随机的时间为2分钟后执行,也即是08分执行,执行时候,先执行了0anacron脚本,然后更新时间。
[root@centos6 ~]# tail -f /var/log/cron
Sep 9 08:06:17 centos6 anacron[6451]: Anacron started on 2022-09-09
Sep 9 08:06:17 centos6 anacron[6451]: Will run job `cron.test' in 2 min.
Sep 9 08:06:17 centos6 anacron[6451]: Jobs will be executed sequentially
........
Sep 9 08:08:17 centos6 anacron[6451]: Job `cron.test' started
Sep 9 08:08:17 centos6 run-parts(/tmp/test_sh)[6516]: starting 0anacron
Sep 9 08:08:17 centos6 anacron[6523]: Updated timestamp for job `cron.test' to 2022-09-09
Sep 9 08:08:17 centos6 run-parts(/tmp/test_sh)[6525]: finished 0anacron
Sep 9 08:08:17 centos6 run-parts(/tmp/test_sh)[6516]: starting 1.sh
Sep 9 08:08:17 centos6 run-parts(/tmp/test_sh)[6532]: finished 1.sh
Sep 9 08:08:17 centos6 run-parts(/tmp/test_sh)[6516]: starting 2.sh
Sep 9 08:08:17 centos6 run-parts(/tmp/test_sh)[6539]: finished 2.sh
Sep 9 08:08:17 centos6 anacron[6451]: Job `cron.test' terminated
Sep 9 08:08:17 centos6 anacron[6451]: Normal exit (1 job run)
[root@centos6 anacron]# ps -ef|grep 6451
root 6451 1 0 08:06 ? 00:00:00 anacron -s cron.test
root 6453 5481 0 08:06 pts/3 00:00:00 grep 6451
[root@centos6 anacron]#
[root@centos6 anacron]# cat cron.test
20220909
[root@centos6 anacron]#
设置开机启动来进行anacron任务
[root@centos6 anacron]# vi /etc/rc.local
/usr/sbin/anacron -s
在crontab中设置定时检查
[root@centos6 anacron]# cat /etc/crontab
* * * * * root /usr/sbin/anacron -s
anacron命令说明
anacron命令
-s 根据/var/spool/anacrontab/*文件中记录的时间来执行所有脚本
-f 强制执行,不去判断记录时间和当前时间的差异
-n 立刻进行未执行的任务,不进行延迟执行
-u 仅仅更新/var/spool/anacrontab/*文件里的时间,不执行job任务
job /etc/anacrontab中的job名称