让一个脚本或者命令在没有任何人为干预的情况下执行往往是非常有用处的。例如,您可能需要让一个脚本去验证(比如说,每隔半个小时验证一次)您网络中的路由器和桥接器都在正确工作,并且在发现问题的时候让它给您发电子邮件。
1 cron: 按时间表执行命令
在 20 世纪 70 年代,cron 最初出现在 UNIX 的大家族中。Linux 发行版本所带版本称为 ISC cron,或者 Vixie Cron,在我所使用的 Ubuntu 10.10 发行版本上是 Vixie Cron,然而不知道什么原因,Fedora 17 系统上的cron 已经改名叫crond 了。
cron 的配置文件称为“crontab”,它是“cron table”的缩写。cron 在 3 个地方查找 crontab 文件:/var/spool/cron(SUSE 上是/var/spool/cron/tabs,而在 Debian 和 Ubuntu 上是/var/spool/cron/crontabs)、/etc/cron.d 和/etc/crontab。
每个用户的 crontab 文件都保存在 /var/spool/cron 目录下。一般而言,一个用户(最多)有一个 crontab 文件。crontab 命令把 crontab 文件传入和传出这个目录。
负责安排由系统管理员制定的系统维护以及其他任务的 crontab 文件,都保存在 /etc/crontab 文件以及 /etc/cron.d 目录下的其他文件里。这些文件的格式与每个用户自己在 /var/spool/cron 下的 crontab 文件格式略有不同,因为它们允许以任何用户身份来执行命令。cron 以完全一样的方式对待/etc/crontab 文件和/etc/cron.d 目录下的文件。一般而言,/etc/crontab 供系统管理员手工维护,而/etc/cron.d 目录则提供了一个地方,软件包把它们可能需要的任何 crontab 项安装在这里。
2 crontab 文件的格式
一个系统上的所有 crontab 文件都使用一种类似的格式。在每一行的第一列中可以使用 "#" 号来引入注释。每个非注释行包含 6 或 7 个字段,它代表一条命令:
minute hour day month weekday [username] command
前 6 个字段用空白隔开,但在 command 字段中的空白则按照原意对待。
crontab 的时间规范如下表所示:
字段 | 描述 | 范围 |
---|---|---|
minute | 分钟 | 0~59 |
hour | 小时 | 0~23 |
day | 天 | 1~31 |
month | 月 | 1~12 |
weekday | 星期 | 0~6(0=Sunday) |
每个和时间相关的字段可以包含:
- 星号,它可以匹配所有字符
- 一个整数,它必须精确匹配
- 用短划线隔开的两个整数,它们匹配的是值的范围
- 一系列用逗号隔开的整数或者范围,它们匹配任何被列出的值
时间范围可以包含一个步长值。例如,时间序列 0、3、6、9、12、15、18 可以更简洁地写成 0-18/3。月份和日期的名字也可以使用易记的文字名。
时间格式
表示“上午 10:45,从周一到周五”。Tips: 不要把星号放在第一个字段中,除非你想让这个命令每分钟都运行。
注意 weekday 字段和 day 字段有潜在的二义性。每一天既是星期中的一天,也是月中的一天。如果同时指定了 weekday 字段和 day 字段,满足两个条件之一的天就被选中。例如:
表示“星期五每半个小时,以及每月 13 号每半个小时”而不是“既是 13 号又是星期五的那天每半个小时”。
command 就是要执行的 sh 命令行。它可以是任何有效的 shell 命令,而且不应该加引号。cron 认为command 一直是这行的末尾,它可以包含空格或者制表符。
cron 使用百分号(%)来表示 command 字段中的换行。只有到第一个百分号之前的文本才会包含在实际命令中,其余行则作为该命令的标准输入。
下面就来看一下 Ubuntu 默认情况下 /etc/crontab 文件的配置情况:
# /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) #
该配置首先指定了执行进程的 SHELL 环境以及 PATH 路径,指定了使用命令的搜索路径。在每个小时的 17 分钟的时候执行一次 /etc/cron.hourly下的所有脚本;每天的 6:25 分检查一下/usr/sbin/anacron 是否为可执行文件,是则执行anacron 所设定的周期性进程;又或者执行/etc/cron.daily 下的所有脚本文件(本人对shell 编程还不太熟悉呀,看上去应该是那个意思吧,有错的地方还请指出,哈哈)。接下来就是每周的执行进程,每月的执行进程。
3 crontab 管理
crontab filename 把 filename 安装为 crontab 文件,它将替换 crontab 文件的任何以前版本。crontab -e 检出 crontab 的一个副本,调用编辑器(由环境变量 EDITOR 所指定)打开它,然后将其重新提交给 crontab 目录。crontab -l 将 crontab 中的内容列在标准输出上,crontab -r 将会删除它,不给您留下 crontab 文件的一点儿内容。
root 可以给 crontab 带一个 username 参数,这样就能够查看或编辑其他用户的 crontab 文件了。
将删除属于用户 devid 的 crontab 文件。
4 cron 的常见用途
Linux 系统经常会带有一些预先安装好的 crontab 项,这些项主要是在 /etc/cron.d 目录下。如果想使这些标准的配置项不起作用,那么可以在每行的开头插入一个 "#" 号,把它们注释掉。不要完全删除它们,也许以后还用得着。
除了采用 /etc/cron.d 目录这种机制外,Linux 发行版本还预先安装了若干 crontab 配置项,它们能运行在一组为大家所熟悉的目录中的脚本,从而给软件包提供了另一种不必对 crontab 文件做任何编辑,就能安装周期性任务的方法。例如,/etc/cron.hourly 每小时运行一次,/etc/cron.daily 每天运行一次,/etc/cron.weekly 每周运行一次,/etc/cron.monthly 每月运行一次。
4.1 清理文件系统
清理系统的垃圾文件问题的一个解决办法就是,用 cron 构造一些在夜间回收磁盘空间的工作,现代的系统一般带有这种功能,但我们最好还是检验一下自己系统的默认行为,确保它适用于您所处的环境。
下面是采用 find 命令的几个惯用方法:
这条命令将删除那些在一个星期中都没有被访问的 core 映像文件。-xdev 参数用来确保 find 命令不会执行到根文件系统之外的文件系统中去,这项限制在那些交叉安装了很多文件系统的网络中是非常重要的。
参数 -type f 很重要,因为 Linux 的内核源代码包括一个目录也叫做 core,不应该删除它。
-name '*~' -o -name '.nfs*' ')' -exec rm -f { } ';'
这条命令将删除那些用 #、.# 或者 .nfs 开头的,或者用 ~ 以及 .CKP 结尾且 3 天内都没有被访问过的文件。不同种类的临时文件和编辑器备份文件都是这一模式的典型代表。
rm -rf { } ';'
这条命令将递归删除 /tmp 下在 72 小时之内没有被修改过的所有子目录。/tmp 中的普通文件会在系统启动时被系统启动脚本删除,但有些系统不会删除目录。如果存在名为lost+found 的目录,那么就要特殊对待而不能删除它。如果/tmp 是一个独立的文件系统的话,这就非常重要了。
5 其他的日程安排程序: anacron 和 fcron
一般而言,cron 不能弥补因为系统宕机或者机器时间出现不连续的情况而错过执行的命令。不过,Vixic Cron 的确在努力。
膝上机以及其他并不长期开机的机器与 cron 的关系更不好,采用 cron 弥补软件对它们有好处。anacron 这个软件对cron 有很好的补充作用,它是一种按照时间间隔来安排任务执行的工具。在anacron 这个软件的世界里,用户只需要求某条特殊的命令每星期执行一次,但用不着指定它在每周一的凌晨 2 点执行。anacron 和cron 不同,它维护着每条命令最近执行时间的记录,所以它只要比较这个时间、指定的时间间隔,以及当前时间就能判定是否需要再次执行命令。
anacron 本身必须在 cron 里使用。虽然 anacron 安排时间的粒度是天,但是每天多运行anacron 几次就会有意义了——如果知道cron 始终能够在每天同一时间运行 anacron,那么可能就不会首先考虑使用 anacron 了。类似地,在系统启动的时候运行 anacron 也会有意义。
fcron 是一种更有雄心弥补 cron 不足的软件,它也包括类似 anacron 的功能,fcron 和anacron 不同,它的目标明显就是要代替 Vixie Cron。它支持几种高级的日程安排方法,用cron 和anacron 配置语言都做不到。不过,人们不得不质疑,比起 fcron 增加的复杂性和使用不标准的日程安排造成的混乱,这些功能的实用价值是否值得。