crontab 介绍

在linux操作系统中,crontab命令用于设置周期性被执行的指令。该命令从标准输入设备读取指令, 并将其存放于“crontab”文件中,以供之后读取和执行。

crontab 系统调度进程。 可以使用它在每天的非高峰负荷时间段运行作业,或在每周或在每月中的不同时段运行。 crontab 可以在无需人工干预的情况下运行作业。crontab命令允许用户提交、编辑或删除相应的作业。

在Linxu中有两种方式创建crontab定时任务:

1、通过crontab配置文件创建定时任务;
2、通过crontab命令创建定时任务;

在工作中,我们一般通过命令的方式来创建定时任务。

crontab 配置

首先让我们来了解一下crontab相关的文件或者文件夹吧:

[root@datacenter01 etc]# ll /etc | grep cron
 
crontab       是设定定时任务执行文件
cron.d        是系统自动定期需要做的任务
cron.daily  是每天执行一次的job
cron.weekly 是每个星期执行一次的job
cron.hourly   是每个小时执行一次的job
cron.monthly  是每月执行一次的job
cron.deny     文件就是用于控制不让哪些用户使用Crontab的功能
anacrontab    anacrontab 的配置文件,关于anacrontab的具体作用我们会在下文说明

当我们要增加全局性的计划任务时,一种方式是直接修改/etc/crontab。但是这种方式无法对定时任务进行有效的归纳管理,所有的定时任务全部放到一个文件,当定时任务多起来之后,维护是一个很大的问题。一般不建议直接在/etc/crontab文件,进行定时任务的配置。

/etc/cron.d目录就是为了解决这种问题而创建的。

例如,增加一项定时的备份任务,我们可以这样处理:在/etc/cron.d目录下新建文件
processmonitor.sh,内容如下:

cd /etc/cron.d
vim processmonitor

# 必须要写日志全路径,不然会报错,如果执行jps这些命令,需要刷新一下环境变量
* 1 * * * root source /etc/profile && /usr/local/monitor/processmonitor.sh >> /usr/local/monitor/processmonitor.log 2>&1

cron进程执行时,就会自动扫描该目录下的所有文件,按照文件中的时间设定执行后面的命令。

忽略输入nohup

有时候我们还会看到在定时任务脚本前面有一个nohup的命令,该命令用于指定后面的脚本忽略输入。

58 23 * * * nohup sh /home/work/update.sh >> /home/work/log/update.log 2>&1

后台执行&

无论是在控制台直接执行,还是在定时任务脚本中,我们在某一条命令的最后面加上&符号,表示当前命令在后台运行,不占用控制台。

58 23 * * * nohup sh /home/work/update.sh >> /home/work/log/update.log 2>&1 &

这里需要注意,如果执行的命令有等待输入的交互,把这个命令使用&放在后台运行时,它会一直等待输入,但是有没有输入,就卡住不动了。

crontab执行时,要读取三个地方的配置文件:一是/etc/crontab, 二是/etc/cron.d目录下的所有文件,三是每个用户的配置文件。

每个用户都会自动生成一个自己的crontab文件,一般位于/var/spool/cron目录下:

[root@localhost cron]# cd /var/spool/cron
[root@localhost cron]# ls
oracle root

如果你用命令crontab -r 就会删除当前用户的crontab文件,例如你切换到oracle账号下,执行了该命令,那么/var/spool/cron/oracle文件就会删除,如果要创建该文件只需要用crontab -e命令即可。

注意,普通用户一般没有权限访问/var/spool/cron

好了,至此我们已经学会了crontab怎么使用了。至于上面的cron.{daily,weekly,hourly,monthly} 和 anacrontab 是 anacrontab 服务的东西,至于anacrontab会在下文介绍。

cron.deny 与 cron.allow文件

系统管理员可以通过cron.deny 和 cron.allow 这两个文件来禁止或允许用户拥有自己的crontab文件。

/etc/cron.deny 表示不能使用 crontab 的用户
/etc/cron.allow 表示能使用 crontab 的用户。

默认情况下,cron.allow 文件不存在。如果两个文件同时存在,那么/etc/cron.allow优先。如果两个文件都不存在,那么只有超级用户可以配置作业。

但是让人纳闷的是cron.deny文件是空的。

crontab 命令

# 查看所有配置的cron任务
crontab -l

# 创建定时任务
crontab -e

# crontab 启动
service crond start
# crontab 服务状态查看
service crond status

crontab 日志文件

如果我们需要查看crontab定时任务运行的日志,可以进入下面的文件夹进行查看:
ll /var/log/cron*

crontab 格式

crontab文件包含6列,每列之间使用空格分隔,每列的要求和含义如下:

第i列	要求	含义
1	0~59	第几分钟
2	0~23	第几小时
3	1~31	几号
4	1~12	几月
5	0~7	星期几
6	command	运行的命令

# 每1分钟执行一次myCommand
* * * * * myCommand

# 每10分钟执行一次myCommand
*/10 * * * * myCommand

anacron 介绍

设想这样一个场景,Linux 服务器会在周末关机两天,但是设定的定时任务大多在周日早上进行,但在这个时间点,服务器又处于关机状态,导致系统很多定时任务无法运行。又比如,我们需要在凌晨 5 点 05 分执行系统的日志备份,但 Linux 服务器不是 24 小时开机的,在晚上需要关机,白天上班之后才会再次开机,在这个定时任务的执行时间我们的服务器刚好没有开机,那么这个定时任务就不会执行了。

anacron 就是用来解决这个问题的。anacron 会以 1 天、1周(7天)、一个月作为检测周期,判断是否有定时任务在关机之后没有执行。如果有这样的任务,那么 anacron 会在特定的时间重新执行这些定时任务。

那么,anacron 是如何判断这些定时任务已经超过执行时间的呢?这就需要借助 anacron 读取的时间记录文件。anacron 会分析现在的时间与时间记录文件所记载的上次执行 anacron 的时间,将两者进行比较,如果两个时间的差值超过 anacron 的指定时间差值(一般是 1 天、7 天和一个月),就说明有定时任务没有执行,这时 anacron 会介入并执行这个漏掉的定时任务,从而保证在关机时没有执行的定时任务不会被漏掉。

在 CentOS 6.x 中,使用 cronie-anacron 软件包取代了 vixie-cron 软件包。而且在原先 CentOS 版本的 /etc/cron.{daily,weekly,monthly} 目录中的定时任务会同时被 cron 和 anacron 调用,这样非常容易出现重复执行同一个定时任务的错误。因此,在 CentOS 6.x 中,/etc/cron.{daily,weekly,monthly} 目录中的定时任务只会被 anacron 调用,从而保证这些定时任务只会在每天、每周或每月定时执行一次,而不会重复执行。 不仅如此,在 CentOS 6.x 中,anacron 还有一个变化,那就是 anacron 不再是单独的服务,而变成了系统命令。也就是说,我们不再使用“service anacron restart”命令来管理 anacron 服务了,而需要使用 anacron 命令来管理 anacron 工作。

anacron 执行流程

我们用 cron.daily 工作来说明一下 /etc/anacrontab 的执行过程:

1、读取 /var/spool/anacron/cron.daily 文件中 anacron 上一次执行的时间。
2、和当前时间比较,如果两个时间的差值超过 1 天,就执行 cron.daily 工作。
3、只能在 03:00-22:00 执行这个工作(此时间可配置)。
4、执行工作时强制延迟时间为 5 分钟,再随机延迟 0~45 分钟(此时间可配置)。
5、使用 nice 命令指定默认优先级,使用 run-parts 脚本执行 /etc/cron.daily 目录中所有的可执行文件。

anacron 命令格式

下面是此命令常用的几个选项及各自的功能:

-f	强制执行相关工作,忽略时间戳。
-u	更新 /var/spool/anacron/cron.{daily,weekly,monthly} 文件中的时间戳为当前日期,但不执行任何工作。
-s	依据 /etc/anacrontab 文件中设定的延迟时间顺序执行工作,在前一个工作未完成前,不会开始下一个工作。
-n	立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间。
-q	禁止将信息输出到标准错误,常和 -d 选项合用。

anacron 配置

[root@localhost ~]# vi /etc/anacrontab
#最大随机廷迟
RANDOM_DELAY=45

#anacron的执行时间范围是3:00~22:00
START_H0URS_RANGE=3-22

#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那就执行
1 5 cron.daily nice run-parts /etc/cron.daily

#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被执行,就会执行
7 25 cron.weekly nice run-parts /etc/cron.weekly

#每隔一个月开机后 45 分钟检查 /etc/cron.monthly 目录内的文件是否被执行,如果一个月内没有被执行,那就执行
©monthly 45 cron.monthly nice run-parts /etc/cron.monthly

在这个文件中,“RANDOM_DELAY”定义的是最大随机延迟,也就是说,cron.daily 工作如果超过 1 天没有执行,则并不会马上执行,而是先延迟强制延迟时间,再延迟随机延迟时间,之后再执行命令;“START_HOURS_RANGE”的是定义 anacron 执行时间范围,anacron 只会在这个时间范围内执行。