http://www.ibm.com/developerworks/cn/education/aix/au-usingcron/index.html#ibm-pcon
使用 cron 进行自动维护
简介: 要想实现连续不停的计算,任务必须能够在任何时候运行。您可以在晚上定时醒来,在几十台机器上登录并输入各种命令;也可以放心地休息,而把工作交给 cron。cron 是一个守护进程,也就是不间断运行的进程,它根据调度计划执行命令。无论白天还是黑夜,无论工作多么繁重,cron 都会毫无怨言地注意时间并按时运行作业。学习如何配置和维护 cron,了解它的众多用途。
开始之前
本节解释本教程讲授什么内容,以及如何从中获得最大的收益。
本教程解释如何配置和维护 cron,cron 是几乎所有 UNIX? 计算机上都有的作业调度程序。另外,本教程演示 cron 的其他一些应用。
学习如何创建、调度和管理 cron 作业,如何通过定义时间表控制作业频率,从每分钟一次到每年一次。另外,学习如何限制访问 cron 以避免滥用,以及如何结合使用其他实用程序和 cron 以自动执行常见的维护任务。
前提条件
本教程针对 UNIX(和类 UNIX)系统的用户和系统管理员。要想学习本教程,您应该熟悉命令行 shell 和 shell 脚本。具备在 UNIX 上安装和配置软件的经验也是有帮助的。
系统需求
要想运行本教程中的示例,需要一台 UNIX 计算机。如果希望配置系统范围的 cron,还需要根访问权。本教程中的示例基于在现代 UNIX 系统上广泛使用的 Vixie cron,并使用 Ubuntu Desktop Linux? version 8.04.1。其他版本的 cron 与 Vixie 相似;具体信息请参见自己的 UNIX 系统文档。
不中断运行
与您和我不同,计算机可以永不疲倦地工作,以相同的精力执行每个任务。另外,计算机可以每周 7 天每天 24 小时连续工作,包括风雪天和公共假日。
cron 守护进程
但是,要想实现连续不停的计算,任务必须能够在任何时候运行。您可以晚上定时醒来,在几十台机器上登录并输入各种命令;也可以放心地休息,把工作交给cron。cron 是一个守护进程(也就是不间断运行的进程),它根据调度计划执行命令。无论白天还是黑夜,无论工作多么繁重,cron 都会毫无怨言地注意时间并按时运行作业。
需要监视 FTP 收存箱(drop-box)接收到的数据吗?使用cron 每几分钟运行一个 shell 脚本。需要删除每天积累的草稿文件吗?在午夜执行垃圾收集。希望定期循环使用日志文件吗?设置一个每周调度计划。
在这里,学习如何配置和维护cron 并了解它的众多应用。具体地说,本教程讨论 Vixiecron,Vixie 这个名称源自它的开发者 Paul Vixie。在 FreeBSD、Apple Mac OS X、大多数风格的 Linux 和其他 UNIX 系统上都可以找到 Vixiecron。要想查明您的系统是否运行 Vixiecron,可以输入man cron 或man crontab,查看末尾是否提到开发者是 Paul Vixie。
要想学习本教程和使用cron,您应该熟悉至少一种文本编辑器,比如 vi 或 Emacs,还应该有使用 UNIX 命令行、shell 脚本和 shell 环境变量的经验。另外,如果希望修改系统范围的cron 配置文件,还必须有根(超级用户)访问权。
了解 cron 概念
cron 守护进程是一个由实用程序和配置文件组成的小型子系统,在几乎所有类 UNIX 系统上都可以找到某种风格的cron。cron 的组件包括守护进程本身;一组系统范围的配置文件;一组针对特定用户的配置文件;一个用来添加、修改和删除用户配置文件的实用程序;以及一个简单的访问控制设施。一般来说,cron 配置文件或cron 作业的列表被称为 crontab 或cron 时间表。
如您所见,不需要为保持系统不间断运行而牺牲您的休息时间。只需确定作业、定义它的调度计划并在适当的 crontab 中设置此作业,然后就可以放心地休息了。现在就来看看cron 文件的特殊语法。
crontab 仅仅是一个文本文件,可以用任何 UNIX 编辑器编辑它。它可以包含四种代码行:空行、注释、环境变量设置和命令。
空行和注释
文件中的空行和多余的空格被忽略。空行和空格有助于提高 crontab 的可读性,使 crontab 组织有序。
还可以使用注释对每个作业的时间表和用途加以说明。要想创建注释,只需在一行的开头加上一个井号(#)。
环境变量和命令
cron 最终使用一个 shell 执行每个命令。可以通过环境变量修改或定制 shell 的行为。
在 crontab 中很容易设置 shell 环境变量。只需输入 VARIABLE=value,把 VARIABLE 替换为变量名,把 value 替换为一个值。例如,crontab 行:
PATH=/usr/bin:/bin:/usr/local/bin
|
指定一个有序的目录列表作为 shell 搜索路径。
cron 预定义了五个环境变量:
要想修改这些默认值或设置任何变量,只需在 crontab 中设置适当的环境变量。
当然,crontab 可以包含任意数量的命令行。每个命令行指定一个频率、一个用户名(只对于系统 crontab)和一个要运行的任务。例如,命令:
5 0 * * * root find /tmp -type f -empty -delete
|
在每天 12:05 a.m(5 0 * * *)删除 /tmp 中的所有空文件和目录(find /tmp -type f -empty -delete)。此作业作为根用户(root)运行。
系统 crontab 命令必须指定一个用户名,作为运行此任务所用的用户。(因此,在 /etc/crontab 中可能看到上面的命令)。针对用户的 crontab 不能指定用户名;一个用户的cron 命令总是作为这个用户运行。是否有用户名是系统 crontab 和用户 crontab 之间的惟一差异。
下面讨论定制时间表的众多方式。
定制时间表
cron 时间表允许以多种方式运行作业,比如每分钟或在特定日期的特定时间。调度的参数非常灵活。
cron 字段
可以通过五个字段调整频率:分、小时、月中日、月份和周中的日期(如周一,周二)。表 1 总结如何调整每个字段。
|
位置 |
字段 |
值 |
说明 |
|
1 |
分 |
0-59 |
|
|
2 |
小时 |
0-23 |
|
|
3 |
月中日 |
1-31 |
与分和小时不同,月中日不是从零开始的。 |
|
4 |
月份 |
1-12 |
月份也不是从零开始的。也可以不使用 1-12 的数字,而是使用月份名的前三个字母,比如 jan 或 may。 |
|
5 |
周中日 |
0-7 |
0 和 7 都代表星期日。还可以使用名称的前三个字母,比如 mon 或 wed。 |
除了名称或数字之外,还可以使用星号(*)表示 “所有”。例如,在分钟位置上的星号表示这一天中的每一分钟。(在某些情况下确实需要如此高的频率,但是一定要小心,以这种频率执行的任务应该非常简单,不会长时间运行)。
还可以使用值的列表、范围和步长(增量)分别指定多个值、连续的值范围和不连续的值范围。甚至可以组合使用列表和范围。列表 是一个逗号分隔的值集。范围 由启始值和结束值(含)以及可选的步长值构成。
我们来看一些示例。表 2 中的每一行包含一个时间表及其说明。当分、小时和日期字段与当前时间匹配时,cron 会执行命令;如果月中日和周中日受到限制(也就是说,不是*),那么当这两个字段中至少一个 与当前时间匹配时,cron 也会执行命令。
|
调度计划 |
|||||
|
分 |
小时 |
月中日 |
月份 |
周中日期 |
说明 |
|
0 |
1 |
15 |
1,3,5,7,9,11 |
* |
在 1、3、5、7、9 和 11 月的 15 日的 1 a.m. 运行命令。为了更容易理解,也可以把这个时间表写成 0 1 15 jan,mar,may,jul,sep,nov *。在指定列表时,不要在逗号后面加空格。 |
|
0-59/15 |
* |
* |
* |
* |
这个调度计划每 15 分钟运行命令一次。 |
|
30 |
* |
* |
* |
wed,fri |
这个时间表只在星期三和星期五每小时的 30 分时执行命令一次。(在列表中可以使用日和月份的名称,但是在范围中不可以)。 |
|
0,30 |
0-5,17-23 |
* |
* |
* |
在午夜到 5 a.m. 以及 7 p.m. 到 11 p.m. 之间整点时和 30 分时运行命令。 |
|
0 |
0 |
1 |
1 |
* |
在每年 1 月 1 日午夜执行命令一次。 |
|
0 |
0 |
* |
* |
0 |
在每个星期日午夜运行命令。这相当于每周一次。 |
|
30 |
0 |
10,20,30 |
* |
6 |
因为月中日和周中日受到限制,这个时间表在每星期六和每月的 10、20 和 30 日(二月除外)的 12:30 a.m. 运行命令。 |
如您所见,实际上可以使用这五个参数指定任何调度计划。为了更加简便,Vixiecron还提供了常用调度计划的简写形式。表 3 列出一些简写形式。
|
简写形式 |
说明 |
|
@reboot |
每当计算机重新引导时运行命令。 |
|
@daily |
每天一次的简写形式。 |
|
@weekly |
每周一次的简写形式。 |
|
@annually |
每年一次的简写形式。也可以写成 @yearly。 |
|
@midnight |
在每天午夜运行命令。这个简写形式相当于 @daily。 |
如果喜欢使用简写形式,只需用它们替代cron 命令的前五个字段。下面这个命令看起来简单多了。
@daily root /usr/local/scripts/clean_old_files.sh
|
crontab 命令示例
掌握了基本概念之后,我们来看一些用户 crontab 命令示例。同样的命令也可以应用系统范围:只需在所有系统 crontab 项中周中日字段(第五个字段)后面指定一个用户名。
要想创建个人 crontab,可以用任何文本编辑器创建一个文件。按照惯例,个人 crontab 文件保存在 ~/.crontab 中,但是可以使用任何文件名。
PATH=/usr/bin:/bin:/usr/local/bin
#
# Every day, print and delete all temporary files whose names begin with '.#'
@daily find $HOME -type f -name '.#*' -print -delete
#
# Every week, show me what is consuming space in my home directory
@weekly du -sh $HOME
|
在编辑文件(比如 ~/mycrontab)之后,通过crontab 实用程序把它提交给 cron:
% crontab ~/mycrontab
|
查看 cron 中存储的信息
要想查看cron 中存储的信息,可以输入crontab -l:
% crontab -l
PATH=/usr/bin:/bin:/usr/local/bin
#
# Every day, print and delete all temporary files whose names begin with '.#'
@daily find $HOME -type f -name '.#*' -print -delete
#
# Every week, show me what is consuming space in my home directory
@weekly du -sh $HOME
|
在任何时候,都可以使用crontab 实用程序替换您的 crontab。只需提交一个新文件或同一文件的修订版。要想删除 crontab 作业,只需输入crontab -r:
% whoami
joe
% crontab ~/mycrontab
% crontab -l
PATH=/usr/bin:/bin:/usr/local/bin
...
% crontab -r
% crontab -l
crontab: no crontab for joe
|
替代 cron 的机制
尽管cron 确实很有用,但是您还应该了解可以替代它的两种机制。
anacron
如果系统常常关机或进入休眠状态(例如,如果使用 UNIX 笔记本计算机的话),那么可以考虑在系统中添加anacron。anacron 与cron 的相似之处在于,它也把作业安排在以后运行;但是,与cron 不同,即使作业的预定运行时间已经过了,anacron 也会运行作业。
例如,如果安排在星期六运行文件系统备份,但是系统在星期五到星期一关机了,那么当系统在星期一重新启动时,anacron 会立即运行星期六的作业。与之相反,cron 仅仅检查现在是否应该运行作业;因此,如果在作业的预定运行时间系统是关闭的,就不运行作业。
anacron 的调度选项比cron 少得多。它只能以整天的时间间隔调度作业,比如一天、7 天或 30 天;但是对于那些必须频繁且可靠地运行的作业,它是更好的选择。
另外,必须从cron 启动anacron。每当anacron 运行时,它读取自己的配置文件。配置文件包含由作业及其频率(用天数表示)组成的配置对。如果作业在预定的时间没有运行,anacron 就运行此作业并记录运行作业的时间。运行完所有作业之后,anacron 退出。
在大多数 Linux 发行版上都可以找到anacron,但是也很容易自己下载并构建源代码。访问 anacron 项目页面 获得最新版本。
anacron 的主要配置文件可以在 /etc/anacron 中找到。可以像配置cron 时那样设置环境变量,但是更简单:
SHELL=/bin/zsh
PATH=/usr/bin:/bin:/usr/local/bin
# format: frequency delay name job
1 10 day-to-day daily.chores.sh
|
第一个数字是周期,所以1 表示每天运行一次,7 表示每 7 天运行一次,等等。第二个数字是延迟,也就是从anacron 启动之后到执行这个作业之间等待的分钟数。如果把延迟字段设置为不同的值,就可以防止所有作业同时启动。名称 day-to-day 只是一个有帮助的昵称。配置行的其余部分指定作业;在这里,每天运行在指定路径中找到的 shell 脚本 daily.chores.sh 一次。
anacron 以手册页形式提供了出色的文档,还可以在网上找到关于anacron 的提示。(请阅读我在 2007 年 10 月编辑的 Rod Smith 撰写的 Linux Magazine 文章)。anacron 适合 UNIX 爱好者和需要额外保障的系统管理员使用。
launchd:cron 的现代替代机制
cron 确实是一种功能强大、值得信赖的实用程序,它的广泛流行就证明了这一点。Vixiecron最近又有所改进,比如增加了简写方式@reboot,进一步简化了管理。但是,cron 仍然有一些缺点:
为了克服这些缺点,Apple Computer 开发了一个统一的启动工具launchd,它可以在引导时、根据需要和按照指定的时间间隔启动进程。实际上,在 Mac OS 10.4 Tiger 中 launchd 已经替代了cron(和init 以及用来引导和初始化系统的其他几个系统实用程序)。(Apple 在系统上保留了cron,以便为用户提供方便,而且 Vixiecron的调度选项更灵活)。Mac OS X 的引导速度很快确实可以归功于launchd:它会在引导时列出要启动的程序,但是只在首次需要时执行程序。
launchd 是开放源码的,可以从 Mac OS Forge 上它的主页获得源代码。目前,launchd 已经被移植到 FreeBSD 上,但是还没有移植到其他 UNIX 或 Linux 系统。但是,许多项目正在积极地实现与launchd 等效的程序,所以简要地了解它的特性是有必要的:
launchd 由三个组件组成:launchd 守护进程本身;用来添加、修改和删除作业以及控制launchd 的 launchctl 实用程序;一个或多个配置文件,每个文件定义一个或多个作业。由于它起源于 Mac OS X,launchd 配置文件只是简单的属性文件,可以用 Extensible Markup Language (XML) 表示。
简单地说,在 Mac OS X 上使用launchd 的步骤如下(要监视一个目录中添加的文件并根据需要运行作业):
可以使用 Mac 的 Property Editor,也可以手工编辑 XML。无论采用哪种方法,产生的文件都应该与 清单 1 相似。
清单 1. 监视文件系统目录变化的 launchd 作业示例
|
简单地说,当 /Users/strike/data/incoming 目录的内容发生变化时,此文件运行 /Users/strike/bin/processor 中的实用程序脚本。把OnDemand 设置为 True 让launchd 根据需要启动此作业。把此文件保存到 ~/Library/LaunchAgents/com.example.processor.plist。
% launchctl load ~/Library/LaunchAgents/com.example.processor.plist
|
4. 如果希望检查最近的操作或查看保存的作业的列表,只需输入launchctl list。
% launchctl unload -w ~/Library/LaunchAgents/com.example.processor.plist
|
7. -w 的作用是什么?它完全删除launchd 中的作业。如果没有这个选项,作业会在登录时自动地重新装载(因为作业还在启动代理的用户集合中)。
launchd 手册页包含大量信息;如果您是 Mac OS X 用户,还可以找到大量针对launchd 的应用程序。一些聪明的开发人员正在把launchd 迁移到更广泛的平台。
使用 cron 让工作更轻松
学习关于使用cron 的一些提示和技巧,了解这个守护进程和相似的其他程序为什么是您的好朋友。
下面是关于cron 的一些提示、技巧和常见的问题:
HOME=/home/joe
PATH=$HOME/bin:/usr/bin:/bin
|
那么 PATH 并不会设置为您期望的路径。您必须手工展开所有变量,比如:
HOME=/home/joe
PATH=/home/joe/bin:/usr/bin:/bin
|
但是,因为每个 cron 命令都由 shell 执行,所以命令可以 引用变量名。例如,如果在个人 crontab 中编写以下命令(注意这一行中省略了用户名参数):
@daily $HOME/bin/cleanup_daily.sh
|
那么 $HOME 会正确地展开。
例如,如果设置SHELL=/bin/zsh,那么所有命令都可以使用 Z shell 的功能,比如它的高级重定向操作符:
SHELL=/bin/zsh
@daily uptime > daily >> weekly
|
在这里,uptime 命令的输出覆盖 daily 文件(>daily)并追加到 weekly 文件中(>> weekly)。
例如,如果 /etc/cron.allow 的内容如下:
joe
zelda
|
那么除 Joe 和 Zelda 之外任何用户都无法访问cron:
% whoami
strike
% crontab ~/.crontab
You (strike) are not allowed to use this program (crontab)
See crontab(1) for more information
|
cron 和与它相似的程序对于系统管理员非常有帮助。如果您需要反复执行相同任务,就可以考虑用cron 实现自动化。捕捉具有许多步骤的复杂任务常常需要 shell 脚本,但是许多任务只需要一行命令。
下面仅仅是一些思路:
@daily joe mysqldump -pjoespwd accounts > $HOME/backups/accounts.`date +%F`.sql
|
每天把数据库 accounts 转储到一个文件。嵌入的日期命令(`date +%F`)确保文件名是惟一的,比如 accounts.2008-08-07.sql。此命令作为用户 joe 运行,所以用-p 指定 Joe 的密码。此命令还可以放在 Joe 自己的 crontab 中,因为转储需要他的 MySQL 凭证。
为了让定位子系统发挥作用,必须定期为文件系统编制索引,因为随时可能添加和删除文件。这种情况就非常适合使用cron。
0 0,12 * * * root updatedb
|
这个 crontab 项每天运行updatedb(locate 更新实用程序)两次。
@midnight www rsync -avz /var/www/site slave1:/var/www
|
在每天午夜,rsync 都会把 /var/www/site 复制(-avz)到 slave1 上的 /var/www。
使用命令行实用程序mail 和 shell 管道操作符(|)把任务的输出发送给团队中的一个或多个成员。
@weekly root df --print-type --local -h |& mail -s "Weekly df report" andy bob
|
在这里,每周通过电子邮件把df 的输出发送给用户 Andy 和 Bob,让他们能够监视磁盘使用量。
结束语
教程结束语
无论您是单独使用 UNIX 系统,还是管理有数百位用户的系统,自动执行维护任务都有助于节省时间、减少错误以及保持机器不间断运行。cron 是在 UNIX 系统上实现自动化的关键组件,只需发挥一点儿想像力,就可以让计算机为您工作,而不是由您 “伺候” 计算机。
cron 有助于更轻松地完成工作。现在,您可以睡个好觉了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21256317/viewspace-1061728/ ,如需转载,请注明出处,否则将追究法律责任。