V o s a m o


Linux计划任务

计划任务

计划任务就是定时或周期执行的一些工作,比如定期发邮件等等。在Linux中,例行性工作是通过crontab和at进行调度的,所谓调度就是将这些工作安排执行的流程。在Linux中有两种工作调度的方式:一种是例行性的,每隔一定的周期执行一次,用crontab来处理;另一种就是一次性的,执行完之后就没了,用at来处理。

一次性的工作

对于一次性的定时任务使用at命令。要使用at命令需要开启atd服务,systemctl start atd

命令格式:

at [参数] [时间]

命令参数:

  • -m 当指定的任务被完成之后,将给用户发送邮件,即使没有标准输出
  • -l atq的别名
  • -d atrm的别名
  • -v 显示任务将被执行的时间
  • -c 打印任务的内容到标准输出
  • -V 显示版本信息
  • -q<列队> 使用指定的列队
  • -f<文件> 从指定文件读入任务而不是从标准输入读入
  • -t<时间参数> 以时间参数的形式提交要运行的任务

at允许使用一套相当复杂的指定时间的方法。他能够接受在当天的hh:mm(小时:分钟)式的时间指定。假如该时间已过去,那么就放在第二天执行。当然也能够使用midnight(深夜),noon(中午),teatime(饮茶时间,一般是下午4点)等比较模糊的 词语来指定时间。用户还能够采用12小时计时制,即在时间后面加上AM(上午)或PM(下午)来说明是上午还是下午。 也能够指定命令执行的具体日期,指定格式为month day(月 日)或mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年)。指定的日期必须跟在指定时间的后面。 上面介绍的都是绝对计时法,其实还能够使用相对计时法,这对于安排不久就要执行的命令是很有好处的。指定格式为:now + count time-units ,now就是当前时间,time-units是时间单位,这里能够是minutes(分钟)、hours(小时)、days(天)、weeks(星期)。count是时间的数量,究竟是几天,还是几小时,等等。 更有一种计时方法就是直接使用today(今天)、tomorrow(明天)来指定完成命令的时间。

使用举例:

实例1:三天后的下午5点执行 /bin/ls

执行命令:at 5pm + 3 days,之后终端如下,要求你输入需要执行的操作或命令,最后要以Ctrl+d结束。

at> /bin/ls
at> <EOT>
job 7 at 2013-01-08 17:00

实例2:明天下午17:20将时间输入到指定文件中

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

计划任务设定后,我们可以使用at -latq命令来查看系统中的at任务。

[liushaolin@mycentos ~]$ atq
2	Sun Jul 17 17:00:00 2016 a liushaolin
3	Fri Jul 15 17:20:00 2016 a liushaolin

显示已经设置的任务内容:at -c 3

删除已经设置的任务:atrm 3at -d 3

at的运行方式:我们使用at这个命令来生成所要运行的工作,并将这个工作以文本文件的方式写入/var/spool/at目录内,该工作便能等待atd这个服务的取用与执行了。并非所有用户都可以进行at调度,/etc/at.allow和/etc/at.deny决定了允许或者禁止那些用户可以进行at调度。

周期性的例行性工作

对于按周期执行的任务使用crontab服务。

命令格式:

crontab [-u username] [-l/e/r]

命令参数:

  • -u:只有root用户才能执行,帮助其他用户新建/删除crontab工作调度
  • -e:编辑crontab的工作内容
  • -l:查询crontab的工作内容
  • -r:删除所有crontab的工作内容,如果想仅删除一项,请使用-e去编辑

和at类似,/etc/cron.allow和/etc/cron.deny允许和禁止那些用户使用crontab进行工作调度。

当用户使用crontab这个命令来新建工作调度之后,该项工作就被记录到/var/spool/cron/里面,而且是以用户名来命名。cron执行的每一项工作都会被记录到/var/log/cron这个日志文件里面。

使用举例:

在终端输入crontab -e后进入编辑界面,然后你就可以定制自己的例行工作了。

实例1:定时发送邮件

0 12  *   *   *  mail buptlsl -s "at 12:00" < /home/buptlsl/.bashrc

我们来看一下这行代码,它的意思是每天的12点给buptlsl发送一封邮件,标题为“at 12:00”,邮件内容读取自文件/home/buptlsl/.bashrc。

每条任务都有6个字段,前5个字段为时间字段,最后一个是命令字段。如下:

代表意义 分钟 小时 月份 命令
数字范围 0-59 0-23 1-31 1-12 0-7 命令

时间字段有几点需要指出:

  • 周的数字0或7都代表周日。
  • /n表示每隔n个时间单位间隔执行一次,例如每5分钟执行一次即为:/5 * * * * command也可以写成0-59/5
  • *表示任何时刻都接受的意思
  • ,逗号表示分隔时间段的意思,如果执行命令的时刻为3时或6时,则为* 3,6 * * * command
  • -表示一段时间范围,例如8点到12点,用8-12表示

系统crontab配置

前面的crontab -e是针对用户设计的,创建的任务会保存在/var/spool/cron/username中,而系统的例行性工作都在/etc/crontab这个文件中,只需要编辑这个文件就可以修改系统的例行性工作了。crond服务会每分钟去读取一次/etc/crontab文件和/var/spool/username文件夹里面的内容来主执行例行任务。所有的系统计划任务最好都放在/etc/crontab

需要区别的是,crontab -e这个crontab其实是/usr/bin/crontab这个执行文件,但是/etc/crontab是一个纯文本文件。

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  *  command to be executed

MAILTO=root表示当例行性命令有错误或者有输出结果时,会将信息传给root,这个地方可以改成你自己的邮箱,例如:haha@gmail.com

更多例子:

1 * * * * root run-parts /etc/cron.hourly //每个小时去执行一遍/etc/cron.hourly内的脚本
2 4 * * * root run-parts /etc/cron.daily //每天去执行一遍/etc/cron.daily内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly //每星期去执行一遍/etc/cron.weekly内的脚本
42 4 1 * * root run-parts /etc/cron.monthly //每个月去执行一遍/etc/cron.monthly内的脚本

时间字段和命令字段之间有一个身份字段,表示执行命令的用户身份,此处为root。

新技能

观察crontab任务的写法你可以看出执行crontab任务的最小时间单位是minute,假如我希望能够每隔10s执行一次任务呢?这种情况可以借助crontab + sleep来实现。

* * * * * php /home/fdipzone/php/crontab/tolog.php
* * * * * * sleep 10; php /home/fdipzone/php/crontab/tolog.php
* * * * * * sleep 20; php /home/fdipzone/php/crontab/tolog.php
* * * * * * sleep 30; php /home/fdipzone/php/crontab/tolog.php
* * * * * * sleep 40; php /home/fdipzone/php/crontab/tolog.php
* * * * * * sleep 50; php /home/fdipzone/php/crontab/tolog.php

当然这种方法比较粗暴并且丑陋,所以可以借助脚本来实现。

首先,编写shell脚本crontab.sh

#!/bin/bash
step=10 #间隔的秒数,不能大于60
for (( i = 0; i < 60; i=(i+step) )); do
    $(php '/home/fdipzone/php/crontab/tolog.php')
    sleep $step
done
exit 0

然后创建计划任务:

* * * * * /home/liushaolin/php/crontab/crontab.sh
vosamo /
Published under (CC) BY-NC-SA in categories Linux  tagged with Linux