anacron 是干什么的呢?
简单说吧,crontab 可以指定任务在每天几点钟运行,可是如果那个钟点机器没有开,
那个任务便错过了时间在一个新的时间轮回之内不再运行了。
而 anacron 可以在每天、每周、每月(时间轮回天数可以自己指定)服务启动时便会
将所有服务置为 Ready 状态,只等时间一到,便执行任务。
说得有点别扭,一起来从配置文件入手来分析 anacron 吧。
anacron 的执行方式。
这玩意儿远看蛮简单的,可是真操作起来就没那么轻松了,这不,我和鲁莹一起讨论了半天,也只有那么一点点苗头。
anacron 是干什么的呢?简单说吧,crontab 可以指定任务在每天几点钟运行,可是如果那个钟点机器没有开,那个任务便错过了时间在一个新的时间轮回之内不再运行了。而 anacron 可以在每天、每周、每月(时间轮回天数可以自己指定)服务启动时便会将所有服务置为 Ready 状态,只等时间一到,便执行任务,说得有点别扭,一起来从配置文件入手来分析 anacron 吧。
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
1 5 cron.daily run-parts /etc/cron.daily
7 70 cron.weekly run-parts /etc/cron.weekly
30 75 cron.monthly run-parts /etc/cron.monthly
首先前两行注释,告诉你文件是做什么用的,从 man 5 anacrontab 获取配置文件帮助。
第5、6行是定义基本环境变量,保证程序可以正常运行。
最后三行是默认配置下所执行的任务,也是最重要的,任务配置部分。
分三部分:
period delay job-identifier command
<轮回天数> <轮回内的重试时间> <任务描述> <命令>
7 70 cron.weekly run-parts /etc/cron.weekly
首先是轮回天数,即是指任务在多少天内执行一次,monthly 就是一个月(30天)内执行,weekly 即是在一周之内执行一次。
其实这种说法不太好,因为它用的不是人类的日历来定启动任务的时间,而是利用天数,像"每月",是指在"每月"执行的任务完成后的三十天内不再执行第二次,而不是自然月的"三十天左右",不管什么原因(比如关机了超过一个月),三十天后 anacron 启动之时该任务依然会被执行,"周"任务同理。
第二部分 delay 是指轮回内的重试时间,这个意思有两部分,一个是 anacron 启动以后该服务 ready 暂不运行的时间(周任务的 70 delay 在 anacron 启动后70分钟内不执行,而处于 ready 状态),另一个是指如果该任务到达运行时间后却因为某种原因没有执行(比如前一个服务还没有运行完成,anacron 在 /etc/init.d 的脚本中加了一个 -s 参数,便是指在前一个任务没有完成时不执行下一个任务),依然以周任务和月任务为例,周任务在启动 anacron 后的 70 分钟执行,月任务在服务启动后 75 分钟执行,但是,如果月任务到达服务启动后 75 分钟,可是周任务运行超过5分钟依然没有完成,那月任务将会进入下一个 75 分钟的轮回,在下一个 75 分钟时再检查周任务是否完成,如果前一个任务完成了那月任务开始运行。
(这里有一个问题,如果周任务在后台死掉了,成僵尸进程了,难道月任务永远也不执行?!)
第三部分 job-identifier 非常简单,anacron 每次启动时都会在 /var/spool/anacron 里面建立一个以 job-identifier 为文件名的文件,里面记录着任务完成的时间,如果任务是第一次运行的话那这个文件应该是空的。这里只要注意不要用不可以作为文件名的字符串便可,可能的话文件名也不要太长。
第三部分最为简单,仅仅是你想运行的命令,run-parts 我原以为是 anacron 配置文件的语法,后来才看到有一个 /usr/bin/run-parts,可以一次运行整个目录的可执行程序。
实战自运行任务,让我们以两种不同的方式写一个自己运行的任务,这样就更好理解了!
写一个 /etc/cron.daily/wall.cron,内容为如下:
wall anacron is running/!
ps -aux | tee /tmp/anacron-$.ps
pstree > /tmp/pstree-$.log
然后将 r -f /var/spool/anacron/* 将所有任务置为都未完成的状态,重新启动 anacron: service anacron restart,可以 ps -A 看看,anacron 已经运行在后台了。
等5分钟以后(因为还有其它任务在运行,时间可能会微微多于5分钟),屏幕上将输出 anacron is running! 同时 /tmp 下也留下两个文件:anacron-
.ps和pstree
.log,$$ 为当时 anacron 的进程号。
还有一种写法直接写入 /etc/anacrontab,一步一步来,把 /etc/anacrontab 中的 daily, weekly, monthly 三行注释掉,然后在末尾加入一行:
1 1 anacron.test /etc/cron.daily/wall.cron
删除 /var/spool/anacron 目录中的文件后重新启动 anacron 服务,等一分种过去之后屏幕上又会输出成功的信息:anacron is running!
任务完成之后用 ps -A 查看运行中的进程,会发现 anacron 在运行完所有任务之后自动退出了。
这使鲁莹引出了一个问题:anacron 完成所有任务退出之后,如果不关机或者重新启动 anacron 服务,进入下一个时间轮回,由谁来启动那些任务呢?
确实是个问题,我想要不在 anacrontab 指定一个很大很大的天数,让 anacron 永远也不退出(36500 一百年够了吧。 ^_^),要不系统会每隔一个月调用一次 anacron(manpage 好像是这么写的)。