crond 定时任务调度

crond 定时任务调度

crontab cron table

Linux crontab 是用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond 命令每分钟(这是定时配置的最小粒度)会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。我通过 crontab -e 新建了定时任务之后在下一分钟 0 秒就开始执行了。有的 Linux 发行版 crontab 是读入到内存中的,所以编辑文件后,并不会立即生效,这时候至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行(service crond restart 或者使用 systemctl restart crond)。

而 linux 任务调度的工作主要分为以下两类:

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

说明:

crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表 cron table。(其实时间表达式类似一个正则,当前的时间如果符合这个正则,则会执行特定的程序)

参数说明:

-l -r -e 不能同时使用,从功能上来说就可以猜到不能同时使用

编辑定时任务

执行 crontab -e,然后输入定时任务配置即时间 + 程序,比如:

* * * * * date

意思是每分钟输出一次时间,然后保存退出。编辑完,保存之后就立即生效了,注意:定时任务里的程序执行的结果(即默认输出到标准输出的内容)是不会直接显示在终端中,而是把输出到标准输出的内容以邮件的形式发送到 /var/spool/mail/$USER 文件中(在我这就是 /var/spool/mail/lk,注意,这是个文件,不是文件夹),收到邮寄的提醒也不会自动出现在终端,而是在终端运行命令的时候(也就是输出标准输出的时候)带出来,感觉是把邮件提醒追加到了标准输出的后面,输出标准输出的时候才会带出来。

如果你不希望收到这样的邮件,就把执行结果重定向到别的地方,比如在每一行空一格之后加上 > /dev/null 2>&1 (这个语句的含义我们已经在《Linux 文件系统基础》的 /dev/null文件 小节中解释过)比如

* * * * * date > /dev/null 2>&1

当然你可以可把执行结果重定向到别的文件中,

* * * * * date >> /tmp/crondate.txt

没有邮件了,自然就不会有邮件提醒


你也可以把时间 + 命令的配置写到文件里,一行一条,然后通过 crontab 来调用,调用之后就立即生效了,

crontab cronfile.txt

注意,这个时候,crontab 之前的配置就被覆盖了,而且没有参数可以修改为追加。不过通过 crontab cronfile.txt 写入的定时任务配置,通过 crontab -e 是可以继续编辑的,那如果我想实现追加的效果怎么办呢,很简单,把命令行放到 sh 文件中,比如 ~/cronfile.sh,赋予执行权限,然后在 crontab -e 中加一行,调用 cronfile.sh 脚本即可,秒啊!

* * * * * sh ~/cronfile.sh > /dev/null 2>&1


如果出现程序单独可以执行,但是配合写到定时任务里就是无法执行(这种情况有时候会出现,有时候不会出现,很玄学,出现这种情况的一般都是脚本),这主要是因为无法读取环境变量的原因。解决办法:

关于不同的 Bash 进程的配置文件的加载,请看《Bash 启动时的配置文件加载》

定时时间配置

CRON 表达式校验网址:crontab guru

配置定时任务的时候最重要的就是时间部分的配置

时间格式如下:口诀是 分时日月周

f1   f2   f3   f4   f5   program
*    *    *    *    *
|    |     |    |     |
|    |     |    |     +----- 星期中星期几 (0 - 6) (星期天 为0),或者直接写sun , mon , tue , wed , thu , fri , sat
|    |     |    +---------- 月份 (1 - 12) 或者直接写 jan , feb , mar , apr  ...
|    |     +--------------- 日期,一个月中的第几天 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)  

其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。

简单实践:

1-10/2 * * * *:从第 1 分钟到第 10 分钟,每两分钟执行一次

1-10/2,20,30-40 * * * *:从第 1 分钟到第 10 分钟,每两分钟执行一次,同时第 20 分钟执行一次,第 30-40 分钟一直执行(每分钟执行一次)

cron 和 crond、crontab

cron 是 Linux 内置计划任务服务的名称,crond 是这个服务的进程名称,crontab 是用来创建定时任务的命令,你可以把 crontab 编辑的文件看作是 cron 的配置文件,也可以叫它作业列表。

核心配置文件

涉及到的文件:

crond 进程每分钟会定期检查三个目录或文件中是否有要执行的任务,1 是 /etc/crontab,2 是 /etc/cron.d 目录下的所有文件,3 是每个用户的配置文件,即 /var/spool/cron/$USER,如果当前时间跟定时任务配置文件中的时间匹配上了,就会自动执行该任务。因此,计划任务运行的最小时间间隔是 1 分钟,也就是说任务最频繁只能每分钟运行一次。

除了 /var/spool/cron/$USER 以外,/etc/crontab/etc/cron.d 的定时任务配置文件都要指定执行人 user,其实定时任务都需要要执行人,只是 /var/spool/cron/$USER 的执行人已经确定是 $USER,不需要再手动指定而已,这个执行人的意思是命令由谁来执行,以谁的角色,谁的权限来运行,首先执行人信息在日志记录中就会体现,同时定时任务涉及到的文件和目录的权限问题也会以执行人的权限为参考,如果不指定则会报错。

* * * * * user-name command to be executed

其他文件或者目录

下面这三个文件夹由 anacron 执行

选用哪种定时任务配置方式最合适

对于普通用户而言,几乎没有权限来操作上面提到的各种文件夹和目录,就算是操作用户自身的定时任务 /var/spool/cron/$USER 文件,也无法直接编辑,而是需要通过 crontab -e 命令,所以普通用户只有这一种方式编辑定时任务。

对于 root 用户,有 4 种设置方式编辑定时任务

  1. 命令 crontab -e 内容在文件 /var/spool/cron/root

  2. /etc/crontab 文件

  3. /etc/cron.d 目录下新建一个文件

  4. /etc/cron.daily//etc/cron.hourly//etc/cron.weekly//etc/cron.monthly/

这 4 中应该选哪一种比较好呢?:

先排除 1,2 里面有环境变量,3 里面没有环境变量,2 和 3 格式一样。3 里面文件名字可以自定义,看起来清晰一点,找起来,替换起来很方便,写到 2 里的话还得去找。4 里面,一个目录下如果由多个文件貌似只能使用同一个时间执行。

总之,一般情况下用 /etc/cron.d 就行了

crond 服务管理

由于 crond 是 Linux 的内置服务,可以用以下的方法启动、关闭这个服务:

service crond status:查看状态

service crond start:启动服务,需要 root 权限

service crond stop:关闭服务,需要 root 权限

service crond restart:重启服务,需要 root 权限

service crond reload:重新载入配置,需要 root 权限

应该注意的问题: