旷世的忧伤

Huoty's Blog

Linux计划任务(at batch crontab anacron)

at在未来只做一次任务调度,依赖于atd 服务;batch 命令被用来在系统平均负载达到 0.8% 以下时执行一次性的任务;cron 在未来周期性的执行任务,依赖于 crond 服务;anacron 用于在开机时执行上次停机时没有完成的 crontab 任务,依赖于anacron服务。

at

Ubuntu系统需要手动安装:

apt-get install at

at 命令被用来在指定时间内调度一次性的任务。命令格式如下:

at [-mldv] TIME

选项与参数:

-m :当at的任务完成后,即使没有输出信息,也以 email 通知给使用者
-l :列出目前系统上面的所有该使用者的at任务(同atq)
-d :可以取消一个在 at 任务(同atrm)
-v :可以使用较明显的时间格式列出 at 任务
-c :可以列出后面接的该项任务的内容
-I : atq的别名
-V : 显示版本信息
-q<列队> : 使用指定的列队
-f<文件> : 从指定文件读入任务而不是从标准输入读入
-t<时间参数> : 以时间参数的形式提交要运行的任务

at命令的时间格式:

now + 时间: 时间以 minutes、hours、days、或 weeks 为单位
HH:MM: 24小时制度,如果时间已过,就会在第二天的这一时间执行
midnight: 表示00:00
noon: 表示12:00
teatime: 表示16:00

示例:

[root@localhost ~]# at 17:20 tomorrow
at> date >/root/2013.log
at> <EOT>
job 8 at 2013-01-06 17:20

batch

batch 命令被用来在系统平均负载达到 0.8% 以下时执行一次性的任务,通俗的所就是系统空闲时执行任务。用法与at一样 。

需要注意的是, /etc/at.allow/etc/at.deny 文件可用来限制对 at 和 batch 命令的使用(root用户不受其控制)。这两个使用控制文件的格式都是每行一个用户(不允许空格),且文件修改后,atd守护进程不需重启。如果at.allow文件存在,那么只有其中列出的用户才被允许使用at或batch命令,且忽略cron.deny文件。如果at.allow文件不存在,那么所有在cron.deny中列出的用户都将禁止使用at和batch.。

Crontab

Crontab 用于定时的执行某项任务,其运行通过 cron 守护进程来完成,进程每分钟会定期检查是否有要执行的任务。

cron 服务通过 crontab 命令来设定具体的周期性任务,我们可以在固定的间隔时间执行指定的系统指令或一些脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令对于需要周期性运行的程序是非常有用的。

命令格式:

crontab [-u user] file

crontab [ -u user ] [ -i ] { -e -l -r }

参数说明:

  • -u user:用来设定某个用户的crontab服务;
  • file:file 是命令文件的名字,表示将 file 做为 crontab 的任务列表文件并载入 crontab。如果在命令行中没有指定这个文件,crontab 命令将接受标准输入(键盘)上键入的命令,并将它们载入 crontab。
  • -e:编辑某个用户的 crontab 文件内容。如果不指定用户,则表示编辑当前用户的 crontab 文件。
  • -l:显示某个用户的 crontab 文件内容,如果不指定用户,则表示显示当前用户的 crontab 文件内容。
  • -r:从 /var/spool/cron 目录中删除某个用户的 crontab 文件,如果不指定用户,则默认删除当前用户的 crontab 文件。
  • -i:在删除用户的 crontab 文件时给确认提示。

需要注意的是,Linux 下的 cron 任务调度分为两类:系统任务调度和用户任务调度。

系统任务

系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。 /etc/crontab文件包括下面几行:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

crontab的文件格式:

  • 第1列 分钟0~59
  • 第2列 小时0~23(0表示子夜)
  • 第3列 日1~31
  • 第4列 月1~12
  • 第5列 星期0~6(0表示星期天)
  • 第6列 运行命令的用户
  • 第7列 要运行的命令

时间配置的特殊字符:

  • 星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
  • 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
  • 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
  • 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

用户任务

用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的 crontab 件都被保存在 /var/spool/cron 目录中,用户任务的配置文件中不需要指定运行用户字段。其文件名与用户名一致,使用者权限文件如下:

  • /etc/cron.deny 该文件中所列用户不允许使用 crontab 命令
  • /etc/cron.allow 该文件中所列用户允许使用 crontab 命令
  • /var/spool/cron/ 所有用户 crontab 文件存放的目录,以用户名命名

可以用 crontab -e 来编辑用户任务,EDITOR 环境变量可以用来指定编辑器,例如设置编辑器为 vim:

export EDITOR=vim;

笔记:在 vim 下如果要查看当前文件所在路径,可以先按下数字1,然后按下组合键 CTRL + G.

重要经验

系统级任务调度主要完成系统的一些维护操作,用户级任务调度主要完成用户自定义的一些任务,可以将用户级任务调度放到系统级任务调度来完成(不建议这么做)。但是反过来却不行,root 用户的任务调度操作可以通过 crontab -u root –e 来设置,也可以将调度任务直接写入 /etc/crontab 文件。需要注意的是,如果要定义一个定时重启系统的任务,就必须将任务放到 /etc/crontab 文件,即使在 root 用户下创建一个定时重启系统的任务也是无效的。

每条任务调度执行完毕,系统都会将任务输出信息通过电子邮件的形式发送给当前系统用户,这样日积月累,日志信息会非常大,可能会影响系统的正常运行,因此,将每条任务进行重定向处理非常重要。 例如,可以在 crontab 文件中设置如下形式,忽略日志输出:

0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1

/dev/null 2>&1 表示先将标准输出重定向到 /dev/null,然后将标准错误重定向到标准输出,&1 表示文件描述符 1。由于标准输出已经重定向到了 /dev/null,因此标准错误也会重定向到 /dev/null,这样日志输出问题就解决了。

另一个需要注意的地方在于,你可以分别以周或者是日月为单位作为循环,但你不可使用 几月几号且为星期几 的模式工作,也就是说周与日月不可同时并存。

如果要设置秒级别的任务,可以通过 sleep 命令来完成,例如 30 秒执行一次 rm -rf /tmp/*

* * * * * rm -rf /tmp/*
* * * * * sleep; rm -rf /tmp/*

anacron

cron是用来控制循环执行的例行性工作的,可循环的时间为分钟、小时、每周、每月或每年等。比如我要设定机器每天早上8点进行备份,就可以用到这个服务。除非我们的机器保持每天都24小时开始,否则就会有些系统例行工作都没有人做了,这个时候就可以用到anacron了。

anacron 并不是用来取代cron的,anacron 存在的目的就在于我们上面提到的,在处理非 24 小时一直启动的 Linux 系统的 cron 服务的执行!所以 anacron 并不能指定何时执行某项任务, 而是以天为单位或者是在开机后立刻进行 anacron 的动作,他会去侦测停机期间应该进行但是并没有进行的 cron服务,如果有就将该任务执行一遍,然后就自动停止。

anacron会以一天、七天、一个月周期去侦测系统中未进行的crontab任务,因此对于某些特殊的使用环境非常有帮助。anacron会去会去分析现在的时间与时间记录档所记载的上次运行anacron的时间,两者比较厚若发现有差异,也就是在某些时刻没有进行crontab,那么此时anacron就会开始执行未运行的crontab了。所以anacron也是听过crontab来运行的,因此anacron运行的时间通常由两个,一个是系统启动期间运行,一个是写入crontab的排程中,这样才能够在特定时间分析系统未进行的crontab工作。我们可以使用 ll /etc/cron*/*ana* 的方式来查看anacron的侦测时间。但是我们仔细分析该文件的话,发现它主要是执行anacron命令。

anacron命令的语法如下:

  • (1) -s开始连续的运行各项工作,会一句时间记录当的数据判断是否进行。
  • (2) -f强制进行,而不去判断时间登录档的时间戳。
  • (3) -n立即进行未进行的任务,而不延迟等待时间。
  • (4) -u仅升级时间记录当的时间戳,不进行任何工作。

而anacron的配置文件是 /etc/anacrontab,而它的很多内容则是在/var/spool/anacron里面保存。当anacron下达anacron -s cron.daily时,它会有如下的步骤:

  • (1) 由/etc/anacrontab分析到cron.daily这项工作名称的天数为一天。
  • (2) 由/var/spool/anacron/cron.daily取出最近一次运行anacron的时间戳。
  • (3) 把取出的时间戳与当前的时间戳相比较,如果差异超过了一天,那么就准备进行命令。
  • (4) 若准备进行命令,根据/etc/anacrontab的配置,将延迟65分钟。
  • (5) 延迟时间后,开始运行后续命令,也就是run-parts /etc/cron.daily这串命令。
  • (6) 运行完毕后,anacron程序结束。
Top