Linux系统命令及Shell脚本实践指南
上QQ阅读APP看书,第一时间看更新

2.4 例行任务管理

日常生活中常会有很多例行性的事情,比如说每周工作日的闹钟、每年一次的生日提醒等。还有一些事情是偶发性的,比如突然需要处理一封紧急的邮件等。在Linux中也有处理这两种任务的方法。如果任务是周期性执行的,其命令为cron;如果只是在某一个特定的时间执行一次,其命令为at。

2.4.1 单一时刻执行一次任务:at

记得以前上网是需要用电话拨号的,不仅网速慢而且资费贵。有时候想要下载一些好玩的游戏软件,需要耗时很久,坐在那干等让人很着急。虽然随着技术和网速的发展,现在有很多下载工具都会在下载后自动断网或关机,但是当时并没有这些功能,于是我想了一个比较笨的办法,就是预估软件下载完成所需要的时间,然后在时间到了的时候自动关机。比如从现在开始,设置30分钟后自动关机,这时就可以使用at命令。

[root@localhost ~]# at now + 30 minutes
at> /sbin/shutdown-h now
at> <EOT>
job 1 at 2012-11-06 23:39

其中,第一行是定义从现在开始算,30分钟后安排一个任务;第二行是到了时间后执行关机操作;第三行是个<EOT>,这不是使用键盘输入的,而是使用了组合键Ctrl+D,表示输入结束;第四行是系统提示有一个任务将在23:39被执行。可以使用atq命令查看当前使用at命令调度的任务列表,第一列是任务编号;也可以使用atrm删除已经进入任务队列的任务,再使用atq查询时,发现已经没有任务列表了,如下所示:

[root@localhost ~]# atq
1       2012-11-06 23:39 a root #查询at的任务队列,第一个数字代表该任务的标号
[root@localhost ~]# atrm 1 #删除标号为1的任务

使用at还可以安排在具体的时间执行任务,比如说在午夜12点实现自动关机,如下所示:

[root@localhost ~]# at 00:00 2012-11-07
at> /sbin/shutdown-h now
at> <EOT>
job 2 at 2012-11-07 00:00
[root@localhost ~]# atq
2       2012-11-07 00:00 a root

默认情况下,所有用户都可以使用at命令来调度自己的任务,如果由于特殊的原因需要禁止某些用户使用这个功能,可以将该用户的用户名添加至/etc/at.deny中。

2.4.2 周期性执行任务:cron

有一些任务是需要周期性执行的,比如说每天早晨的闹钟会在设定的时间准时响起。在Linux中,可以利用cron工具做这种设置。首先需要确定crond进程在运行,如果没有运行,需要先启动该进程。

[root@localhost ~]# service crond start
Starting crond: [  OK  ]
[root@localhost ~]# service crond status
crond (pid  3257) is running...

用户可通过crontab来设置自己的计划任务,并使用-e参数来编辑任务。在这之前需要先了解一下设置的“语法”,当使用crontab-e进入编辑模式时,需要编辑执行的时间和执行的命令。在下面的示例中,前面5个*可以用来定义时间,第一个*表示分钟,可以使用的值是1~59,每分钟可以使用*和*/1表示;第二个*表示小时,可以使用的值是0~23;第三个*表示日期,可以使用的值是1~31;第四个*表示月份,可以使用的值是1~12;第五个*表示星期几,可以使用的值是0~6,0代表星期日;最后是执行的命令。当到了设定的时间时,系统就会自动执行定义好的命令,设置crontab的基本格式如下所示。

*  *  *  *  * command

设置crontab的语法比较难以理解,这里举一些例子方便大家更好地理解,如下所示:

*  *  *  *  * service httpd restart
*/1  *  *  *  * service httpd restart
#这两种写法其实是一致的,都是每分钟重启httpd进程。请注意,这只是一个例子,
除非你有确定的目的,否则不要在实际生产环境中这么设置
*  */1  *  *  * service httpd restart
#每小时重启httpd 进程

* 23-3/1 * * * service httpd restart #从23点开始到3点,每小时重启httpd 进程
30 23 * * * service httpd restart #每天晚上23点30分重启httpd进程
30 23 1 * * service httpd restart #每月的第一天晚上23点30分重启httpd进程
30 23 1 1 * service httpd restart #每年1月1日的晚上23点30分重启httpd进程
30 23 * * 0 service httpd restart #每周日晚上23点30分重启httpd进程

设置完成后,可以使用crontab-l查看设置的任务,也可以使用crontab-r删除所有的任务,如下所示:

[root@localhost ~]# crontab-l
30 23 *  *  0 service httpd restart
[root@localhost ~]# crontab-r
[root@localhost ~]# crontab-l
no crontab for root

与at类似,每个用户都可以设置自己的crontab,如果由于特殊的原因需要禁止某些用户使用这个功能,可以将该用户的用户名添加至/etc/cron.deny中。除了root之外,普通用户只可以设置、查看、删除自己的计划任务,root可以使用-u参数查看指定用户的任务。比如root可以查看用户john的任务列表:

[root@localhost ~]# crontab-u john-l

2.4.3 /etc/crontab的管理

通过上一节,我们知道用户可以通过crontab-e命令来编辑定义自己的任务,事实上,系统也有自己的例行任务,而其配置文件是/etc/crontab。我们先来看一下这个文件的内容:

[root@localhost ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly

英语基础比较好的人看到这个配置文件,都能猜出这个配置文件的意思,也就是定义了每小时、每天、每周、每月的任务。实际上cron.hourly、cron.daily、cron.weekly、cron. monthly都是文件夹,文件夹中则定义了具体的任务。

与使用crontab-e编辑的文件不同,“#run-parts”部分的第六列定义了以什么身份执行例行任务。这里的4个任务都是使用root来运行的。第七列定义了使用run-parts方式来运行第八列文件夹中的所有脚本。除了run-parts方式外,也可以使用命令模式运行例行任务,比如下面的例子就是定义了每分钟由root执行一次答应Hello的操作。

*/1 * * * * root echo "Hello"