计划活动:cron 和 at
Linux 实用工具 cron 和 at 是相关的命令。 cron 实用工具允许您安排重复性任务在任何所需的固定时间间隔执行,而 at 命令允许您指定在某个期望的时间执行一次性操作。 例如,您可以使用 crontab 在每天早上 2 点执行备份,并使用 at 来提醒您当天晚些时候的约会。
“crontab”一词是“chron table”(时间表)的 Unix 术语。 您需要创建符合所需格式的表格,指定命令和执行命令的时间。 您放入表格中的命令可以是任何可执行程序,例如,/usr/bin 中的命令或您编写的 shell 脚本。 您可以使用 crontab 命令来创建、编辑或列出表格,系统 cron 守护进程读取表格并在指定的时间执行命令。
cron 守护进程通常在系统启动时执行,并且不会退出。 在我的 Linux 系统上,cron 守护进程实际上是 Matthew Dillon 的 crond,并在 /etc/rc.d/rc.M 中使用以下行启动
/usr/sbin/crond -l10 >/var/adm/cron 2>&1
在某些 Linux 系统上,使用 Paul Vixie 的 cron 守护进程,在这种情况下,守护进程的名称仅为 cron。 此外,在使用较新版本 init 的系统上,cron 从 /etc/init.d/cron 脚本启动。
您可以使用如下命令检查 cron 守护进程是否在您的系统上运行
$ ps -ax | grep cron raithel 733 pp0 S 0:00 grep cron root 25 ? S 0:00 /usr/sbin/crond -l10
在本例中,我们看到 crond 守护进程确实正在运行。
当 cron 守护进程启动时,它会读取 crontab 目录(通常是 /usr/spool/cron/crontabs)中的各种 crontab 表。 要创建或更改您的 crontab 文件,请使用 crontab 的 -e 选项
$ crontab -e
您将被置于文本编辑器中,其中包含您当前 crontab 文件的副本(如果存在),或者一个空白文件(如果不存在)。 您获得的文本编辑器由您的 VISUAL 环境变量(或 EDITOR,如果未设置 VISUAL)的设置确定,通常是 vi 编辑器(如果您没有另行指定)。
要使用 crontab 计划命令,您必须使用 cron 在 crontab 文件中识别的格式。 此格式不是很直观,所以我创建了一个带有注释掉的标题的 crontab 文件,该标题提供了必要的信息
# minute (0-59), # hour (0-23), # day of the month (1-31), # month of the year (1-12), # day of the week (0-6, 0=Sunday), # command
每个 crontab 条目都是由这六个字段组成的单行,字段之间用空格分隔。 在第一个字段中使用数字 0 到 59 指定命令要执行的分钟,在第二个字段中使用 0 到 23 指定小时,在第三个字段中使用 1 到 31 指定月份中的日期,在第四个字段中使用 1 到 12 指定年份中的月份,并在第五个字段中使用 0 到 6 指定星期几。 将要执行的命令放在第六个字段中。
乍一看,由于有两个“日期”字段(月份中的日期和星期几),可能显得需要冗余或冲突的信息,但这实际上只是为了允许不同的调度算法。 例如,您可能希望每周二被提醒参加会议,或者每月 15 号领取工资。 在您不使用的日期字段中输入星号 (*)。 如果您希望命令在每月 15 号 以及 每周二都执行,则可以同时使用这两个日期字段。
范围用破折号指定。 如果您想指定月份的第 8 天到第 15 天,请在第三个字段中输入 8-15。 字段中非连续的条目用逗号分隔,因此第三个字段中的 1,15 表示本月的 1 号和 15 号。 要指定字段的所有值,例如每年的每个月,请在该字段中输入星号 (*)。 (请注意,要指定每天,您必须在两个日期字段中都输入 *。)
这是一个带有两个条目的 crontab 文件示例
# minute (0-59), # hour (0-23), # day of the month (1-31), # month of the year (1-12), # day of the week (0-6, 0=Sunday) # command 12 4 * * * /usr/local/bin/backup 5 3 10-15 4 * echo "taxes due" | mail jones
注释后的第一行导致备份脚本在每天凌晨 4:12 执行,第二行导致用户 jones 在四月份的六天内收到邮件消息,以提醒税款到期。 通常,最好在非工作时间(如这些时间)执行 crontab 命令,以减少在正常使用时间对系统负载的任何影响。
如果您没有明确重定向标准错误和标准输出,则当命令执行时,它们会作为 crontab 文件的所有者通过邮件发送给您。 在上面的示例中,如果找不到用户 jones,您将收到输出以及错误消息的邮件。
编辑 crontab 文件后,保存并退出编辑器。 将在 crontab 目录中为您创建一个文件。 例如,root 的 crontab 是文件 /usr/spool/cron/crontabs/root。 系统 cron 守护进程会读取此文件并以内部格式存储,它将保留在此处以定期执行,直到它被更改或删除。
要查看您当前的 crontab 文件,请使用 -l(代表“list”)选项
$ crontab -l
要删除您的文件,请使用
$ crontab -d
如果您是超级用户,则可以使用以下命令删除任何用户的 crontab 文件
# crontab -d username
其中 username 是用户的登录名。
上面讨论的 crontab 命令在我的 Linux 系统上运行良好,并且也应该在 System V 和 BSD Unix 系统上运行。 在其他系统上使用 crontab 或将 crontab 文件移动到其他系统时,需要注意的一件事是,某些 cron 守护进程允许超级用户通过创建 cron.allow 和 cron.deny 文件来限制 crontab 服务。 有关详细信息,请参阅特定系统文档。
此外,大多数版本的 cron 都提供一个 /etc/crontab 文件,该文件在其中有一个额外的字段,即执行命令的用户。 同样,请查看您的 cron 版本的文档以获取更多详细信息。
当您想在将来的某个时间执行一次命令或多个命令时,请使用 at。
在 Linux 中,at 命令要求 atrun 命令在 root 的 crontab 文件中启动。 许多 Linux 发行版都启用了 at,但有些没有。 要在您的系统上启用 at 实用工具,请成为超级用户并编辑 root 的 crontab 文件
$ su root Password: # crontab -e
并添加以下行
* * * * * directory/atrun
其中 directory 是 atrun 可执行文件存储的位置。 在我的系统上是 /usr/lib,因此条目是
* * * * * /usr/lib/atrun
这会导致 atrun 每分钟执行一次。 在添加 atrun 行并保存 crontab 文件后的一分钟左右,将评估并执行任何现有的 at 命令(如果时间合适)。 (在此之前,您可能可以输入 at 命令,但它们永远不会执行。)
为了演示 at 命令,让我们让它在几分钟后在您当前的终端窗口中打印“hello”。 首先,获取时间和您当前的终端设备
$ date Tue Oct 3 15:33:37 PDT 1995 $ tty /dev/ttyp2
现在运行 at 命令。 在命令行中指定时间,按 Enter 键,然后输入命令,然后再次按 Enter 键和 Ctrl-D
$ at 15:35 echo "hello" > /dev/ttyp2 ^D Job c00ceb20b.00 will be executed using /bin/sh
at 命令接受输入,直到文件结束字符(通过在行首按 ctrl-D 生成)。 它报告作业号并通知您它将使用 /bin/sh 执行命令。 两分钟后,hello 应该会出现在 /dev/ttyp2 的显示器上。 请注意,您可以输入一系列命令,每行一个命令 — at 将读取每行直到文件结束,并在指定的时间将该文件作为 /bin/sh shell 脚本执行。
假设您想要设置闹钟。 告诉 at 做某事的一种方法是使用相对时间形式,指定相对于 now 的时间。 如果您希望您的计算机在 25 分钟后向您发出哔哔声,请输入
$ at now + 25 minutes echo ^G > /dev/ttyp4 ^D Job c00ceb7fb.00 will be executed using /bin/sh
您将在 25 分钟后听到哔哔声。 在输入时间规范时,允许很大的灵活性。 例如,at 识别军事时间、“am”和“pm”、月份缩写、包含年份的时间表示法等等。 我的 at 手册页甚至声称 at 接受 teatime、noon 和其他结构。 有关有效时间规范的更多示例,请参阅 at 手册页。
您必须告诉 at 您的 tty 位置,否则它不会将输出发送到您的终端窗口。 如果您愿意,您可以接收邮件
$ at 4:55pm Friday echo '5 p.m. meeting with Carol' | mail raithel ^D Job c00ceb7fb.01 will be executed using /bin/sh
要获取您的待处理 at 作业列表,请输入
$ atq
如果您是超级用户,atq 会显示所有用户的待处理 at 作业。 要删除作业,请输入
$ atrm job_number
其中 job_number 是 atq 返回的作业号。 超级用户还可以删除其他用户的作业。
以下是一个简单的脚本,使我更容易使用 at 向自己发送提醒。 该脚本在指定的时间向用户发送邮件,其中包含在提示符下输入的消息行。 它还显示了一些如何指定时间的语法示例,我发现这对于刷新记忆很有用。
请注意,正如编写的脚本,它要求您在您的主目录中有一个 Msgs 目录。 我创建了 $HOME/Msgs,而不是使用像 /usr/tmp 这样的目录,这样消息在被脚本删除之前会更私密。
#!/bin/sh echo "Enter your reminder message. When finished, enter a period (.) at the beginning of a line and press Enter. (Or press Ctrl-C or DEL to exit.)" while : do read MESSAGE if [ "$MESSAGE" = "." ] then break else echo $MESSAGE > $HOME/Msgs/message.$$ fi done cat << !! Enter time and day you want to receive the message, for example: 0815am Jan 24 8:15am Jan 24 now + 1 day 5 pm Friday Then press Enter. !! read TIME echo \ "at $TIME mail $LOGNAME $HOME/Msgs/message.$$" at $TIME << !! mail $LOGNAME < $HOME/Msgs/message.$$ rm -f $HOME/Msgs/message.$$ !! exit 0
不同版本的 Unix 中 crontab 和 at 命令的用户界面非常相似,但底层目录结构、守护进程和访问控制的实现可能有所不同。 请务必查看您的系统文档,以充分利用这些强大命令的各个方面。
crontab 和 at 的用途几乎没有限制,但请允许我提出一些警告。 首先,在启用用户 crontab 和 at 权限时,请考虑安全问题。 显然,心怀不满的同事可能会留下某种“定时炸弹”,其限制仅受其其他权限限制。 许多版本的 crontab 和 at 允许您指定“allow”和“deny”文件来控制哪些用户可以访问这些实用工具。 如果您愿意,您还可以使用 root 的 crontab 来检查和删除用户 crontab(或任何其他文件)。
此外,请彻底调试您的 crontab 文件条目。 检查它们是否工作。 这些条目通常计划在低使用率时段执行,因此您不太可能在当时在场观察它们。
John Raithel 是一位咨询技术作家,专门从事 Unix 操作系统系统和网络管理的文档编写,目前正在为 Silicon Graphics, Inc. 编写万维网和防火墙文档。 他住在美国加利福尼亚州中部海岸的一个小镇上,在那里他玩弄他的 Linux 和 SunOS “迷你网络”。 您可以通过电子邮件 raithel@rahul.net 与他联系。