9.8 用cron进行调度
通常我们需要安排脚本在某个时间或每隔一段时间来运行。GNU/Linux系统包含了各种用于调度任务的工具。cron
就是其中之一,它通过守护进程cron
使得任务能够以固定的时间间隔在系统后台自动运行。cron
利用的是一个被称为“cron
表”(cron table)的文件,这个文件中存储了需要执行的脚本或命令的调度列表以及执行时间。这个工具非常有用,一个常见的用例是设置在免费时段(free hour)(这是一些ISP提供免费服务,通常将时间设定在大多数人都已入睡的午夜)从Internet上进行下载。用户完全不需要在夜里熬红双眼等待下载。只需要编写一个cron
条目,然后调度下载即可。你也可以安排当免费时段结束后自动断开Internet连接并关机。
9.8.1 新手上路
所有的GNU/Linux发行版都默认包含了cron
调度工具。只要我们在cron
表中写入条目,对应的命令就会在指定的时间执行。命令crontab
用来添加调度条目。一次cron
调度其实就是一段简单的文本。每一位用户都有自己的cron
调度,通常这也被称为一个cron
作业(cron job)。
9.8.2 实战演练
要想进行任务调度,我们得知道cron
表的格式。一个cron
作业指定了需要执行的脚本或命令的路径以及执行时间。cron
表的每一个条目都由6部分组成,并按照下列顺序排列:
分钟(0~59)
小时(0~23)
天(1~31)
月份(1~12)
工作日(0~6)
命令(在指定时间执行的脚本或命令)
前5部分指定了某个命令实例所要执行的时间。当然还有其他选项也可用以指定调度时间。
星号(*
)指定命令应该在每一个时间阶段执行。也就是说,如果*
是写在cron
作业中的小时字段中,那么命令就会每小时执行一次。与此类似,如果你希望在某个特定时段执行命令,那么就在对应的时间字段中指定时段,并用逗号分隔(例如要在第5分钟和第10分钟运行命令,那就在分钟字段中输入"5, 10"
)。还有另一个不错的选项可以让我们以特定的时间间隔运行命令。在分钟字段使用*/5
,可以每5分钟运行一次命令。这个技巧可以用在任何时间字段。一个cron
表条目是由一行或多行cron
作业组成的。cron
表条目中的每一行都是一项作业。例如:
- 编写一个crontab条目的样例:
02 * * * * /home/slynux/test.sh
这个cron
作业会在每天各小时的第2分钟执行脚本test.sh。
- 要在每天的第5、6、7小时执行脚本:
00 5,6,7 * * /home/slynux/test.sh
- 在周日的每个小时执行脚本script.sh:
00 */12 * * 0 /home/slynux/script.sh
- 在每天凌晨2点钟关闭计算机:
00 02 * * * /sbin/shutdown -h
现在,让我们看看如何调度一项cron
作业。执行crontab
命令进行调度的方法有很多种。
如果你手动运行crontab
,用选项 -e
输入cron
作业:
- $ crontab -e
- 02 02 * * * /home/slynux/script.sh
当输入crontab -e
后,会打开默认的文本编辑器(通常是vi)供用户输入cron
作业并保存。这项cron作业将会在指定的时间被调度执行。
如果我们在脚本中调用crontab
进行任务调度,那么有另外两种方法可供使用:
- 创建一个文本文件(例如task.cron),并写入
cron
作业。
然后将文件名作为命令参数,运行crontab
:
- $ crontab task.cron
- 通过下面的方法,我们可以在行内(inline)指定
cron
作业,而无需创建单独的文件。例如:
crontab<<EOF
02 * * * * /home/slynux/script.sh
EOF
cron
作业需要写在crontab<
和EOF
之间。
执行cron
作业所使用的权限同执行crontab
命令所使用的权限相同。如果你需要执行要求更高权限的命令,例如关闭计算机,那么就要以超级用户身份执行crontab
。
在cron
作业中指定的命令需要使用完整路径。这是因为执行cron
作业时的环境与终端所使用的环境不同,因此环境变量PATH
可能都没有设置。如果命令运行时需要设置某些环境变量,你应该明确设定出来。
9.8.3 补充内容
crontab
命令还有其他选项。让我们看看其中一部分。
- 指定环境变量
很多命令需要正确的设置环境变量才能够运行。我们可以在用户的cron
表中插入一行变量赋值语句来设置环境变量。
例如,如果你使用的是代理服务器连接Internet,要调度某个需要使用Internet的命令,你就得设置HTTP代理环境变量http_proxy
,可以用下面的方法来完成:
crontab<<EOF
http_proxy=http://192.168.03:3128
00 * * * * /home/slynux/download.sh
EOF
- 查看
cron
表
我们可以用选项-l
列出现有的cron
表中的内容:
- $ crontab -l
- 02 05 * * * /home/user/disklog.sh
crontab -l
会列出当前用户cron
表中的已有条目。
我们也可以通过选项 -u
指定用户名来查看其他用户的cron
表:
- $ crontab -l -u slynux
- 09 10 * * * /home/slynux/test.sh
当使用选项-u
时,你应该使用超级用户以获取更高的权限。
- 移除
cron
表
可以用选项-r
移除当前用户的cron
表:
- $ crontab -r
要移除其他用户的cron
表,可以使用:
- # crontab -u slynux -r
这需要以超级用户身份获得更高的权限。