6.4 作业和任务调度

在UNIX/Linux系统中,除使用相关命令可对正在运行的程序进行管理和控制外,还有相关命令用于对作业进行调度,以规定在指定时刻调度或安排任务的执行。这样做是非常有益的,因为用户可以把那些不急于处理的任务放在系统负载小或非峰值的时间执行,也可以让系统在无用户使用或用户最少的时候重新启动,以保证系统运行的效率。用于作业管理的命令有at、batch和crontab。

6.4.1 at和batch

1.功能与用法

at和batch命令的功能是在某指定时刻调度任务的执行,其用法为:

                at  [-Ⅴ][-f file][-q queue][-mldbv]time
                at  -c job …
                batch  [-Ⅴ][-f file][-q queue][-mv][time]

at从标准输入或指定文件中读取命令并在以后指定的时刻调度它们的执行。at可以接受HH:MM或HHMM形式的时间,以便在以后的指定时间执行命令,默认日期为当天。若当天时间已过,则为下一天。时间还可以跟后缀AM和PM,否则将视为24小时制。用户也可设定today、tomorrow、midnight、noon、teatime(4pm)。还可以同时指定命令执行的时间和日期,日期必须跟在时间的后面,其格式是:① 英文月名 数字日期 [数字年];② MMDDYY;③ MM/DD/YY;④ DD.MM.YY。

用户也可以“当前时间+偏移量”的办法来指定执行时间,这里的偏移量可以是分钟、小时、天或周等。例如,now + 2 minutes、10:22 + 3 days等。

如果在作业操作中未使用I/O重定向,则at在作业执行过程中产生的标准错误和标准输出将以邮件的形式发送给用户。

超级用户可以无条件使用at,对于一般用户能否使用at要根据文件/etc/at.allow和/etc/at. deny来确定。/etc/at.allow、/etc/at.deny文件的结构为每行一个用户的列表,其中不允许出现白空格。如果/etc/at.allow存在,则其中的用户将被允许使用at;若/etc/at.allow不存在,则检查/etc/at.deny,其中的用户将不允许使用at。空的/etc/at.deny意为每个用户均可使用at。如果/etc/at.allow和/etc/at.deny均不存在,则只有超级用户能够使用at命令。与at相关的文件还有/var/spool/at和/var/spool/at/spool。

2.参数说明

at和batch命令的部分参数如表6-7所示。

表6-7 at和batch命令的部分参数

batch是一个shell编写的程序,它通过at提交批处理作业,其用法与at相同。

at和batch为作业提交的客户端程序,由at和batch提交的作业由atd调度执行。

3.示例

1)作业创建

设作业脚本已经编辑好,并存放在文件myjob和myjob1中,可以通过以下方法调度作业执行。

              #at 1200<myjob           #通过输入改道从myjob中读取作业,并规定在12:00执行
              #at 1210-f myjob           #从myjob中读取作业,并规定在12:10执行
              #batch 1202-f myjob1       #从myjob1中读取作业,并规定在12:02执行
              #at 1230                  #标准输入读取作业,并在12:30执行
              at>ls-l>/tmp/`whoami`.a     #进入at界面,输入相关命令。“at>”为提示符
              at>date>>/tmp/`whoami`.a   #继续输入命令
              at>Ctrl_D                 #按Ctrl+D结束作业输入
              at><EOF>                 #at显示此行内容,并覆盖Ctrl+D所在的行

2)列出已提交的作业

              # at -l

3)删除已提交的作业

              #at-d 23 25               #23和25为at-l的输出中的作业编号

6.4.2 crontab

1.功能与用法

crontab命令的功能是规划程序的定时启动、定时执行。crontab是一个客户端程序,用于编辑用户crontab文件。crontab提交的任务由服务器程序crond调度。crond还有按时、日、周和月调试执行的任务,可参阅crond的手册页。

at和batch提交的作业是一次性的,而crontab提交的作业是重复性的、永久性的。当crontab被制定好之后,在下一次被修改之前crond将一直按其内容的规定调度程序的执行。crontab的用法为:

              crontab [-u user] file
              crontab [-u user] [-l | -r | -e] [-i] [-s]

crontab受文件/etc/cron.allow和/etc/cron.deny的控制。如果/etc/cron.allow存在,则只有列在其中的用户才能使用此功能;如果/etc/cron.allow不存在,而/etc/cron.deny存在,则只有不在/etc/cron.deny中的用户才能使用;若两者均不存在,则根据系统配置,可能只有超级用户可使用crontab或所有用户均可使用crontab。在Fedora Core 9中允许所有用户使用crontab。

2.参数说明

crontab命令的参数如表6-8所示。

表6-8 crontab命令的参数

3.crontab文件的内容

系统将为每个可以使用此功能的用户,以用户名在/var/spool/cron下创建与用户名同名的crontab文件,如root、test1等。

用户的crontab文件是由crontab命令来修改的,当使用-e修改用户的crontab文件时,crontab命令自动调用vi对文件进行编辑。当从vi中退出时,将修改后内容回写,任务自动提交。用户也可直接编辑/var/spool/cron/username,例如对于root用户来说,文件为/var/spool/cron/root,修改用户crontab文件,但在保存退出编辑时不能自动提交,只有在系统重启后才能生效。

crontab文件中,#开始的行为注释行,除注释行外的每一有效行由6个用空格分隔的域组成。前面5个是数字,分别是分钟(0-59)、时(0-23)、日期(1-31)、月(1-12,也可以是英文月份名字)和星期(0-6,0表示星期日)。它们可以是以下形式:

(1)数字。

(2)由减号连接的两个数字,表示范围,如1-5表示从1到5。

(3)一组由逗号分隔的数字(枚举),如1,3,5。

(4)*表示所有或任何允许的值。

(5)*/s表示步长,如0-23/2表示从0到23每隔两个单位发生一次,即0,2,4,…。

若在文件中同时指定了两个日期(日期和星期),则两者都有效;如果只想指定一个日期,则只需指定其中一个,而另一个用*表示;文件的第6个域是将要在指定时间执行的命令字符串。命令串中的%(\%除外)将被解释为换行符,%后的内容将作为命令的标准输入。

在crontab文件中也可定义供crond使用的环境变量。一些变量是由crond自动设置的,如SHELL、HMOE和LOGNAME等。它们中的一些是可以被重新定义的,但LOGNAME不能。用户也可定义或修改变量,如MAILTO变量定义在crond执行时发送邮件的用户。定义方法与shell编程相同,例如:

              MAILTO=gjshao

4.示例

1)crontab文件示例

              # #定义环境变量SHELL
              SHELL=/bin/sh
              # #定义邮件接收者
              MAILTO=gjshao
              # #每天的00:05执行$HOME/bin/daily.job(假设的任务和程序)
              5 0***        $HOME/bin/daily.job>>/tmp/out 2>&1
              # #每周日3:30重启系统
              30 3**0       /sbin/init 6
              # #从周一至周五的每天22:00向gjshao发邮件
              0 22**1-5     mail-s"It's 10pm"gjshao%Hi,%%Where are your?%
              # #在偶数点的半点向系统中的用户广播信息
              30 0-23/2 * * * wall "run 30 minutes after midnight, evry 2 hours,everyday"

2)编辑自己的crontab文件

              # crontab -e
              ##进入编辑界面,输入以下内容      ##每周五3:30重启系统
              30 3**5      /sbin/init 6
              # #每个周日的0:30清除/tmp/gjshao*文件
              30 0**0      rm-f/tmp/gjshao*&>/dev/null

3)查看crontab文件的内容

              # crontab -l