Crontab 是 Linux 平台下的一款用于循环执行例行任务的工具,Linux 系统由 cron (crond) 这个系统服务来控制任务 , Linux系统本来就有很多的计划任务需要启动 , 所以这个系统服务是默认开机启动的 。 Linux 为使用者提供的计划任务的命令就是 Crontab
Crontab 是 Linux 下用来周期性执行任务或者等待处理某些事情的时候
Crontab 配置文件
Crontab 的周期性任务主要分为两种:系统任务 / 用户任务
- 系统任务就是系统周期性需要执行的任务,比如说定时执行缓存清理任务,记录日志等等。系统任务的配置文件在 /etc/crontab
这里是 crontab 的配置文件中的内容
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# 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
# | | | | |
# * * * * * user-name command to be executed
前面 4 行用于配置 cron 的环境变量,环境变量的配置不在这里讨论了,之后的内容是 crontab 的用法的一些简单的解释
- 用户的周期性任务就可以使用 crontab 工具,所有用户制定的 crontab 计划任务都被保存在 /var/spool/cron 中,文件名即用户名
Crontab 文件的含义
在上面的crontab文件中已经包含了一部分的解释,这里我将其翻译为中文
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# 详细的解释可以查看 man 手册
# 举例:
# .---------------- 分 (0 - 59)
# | .------------- 时 (0 - 23)
# | | .---------- 日期(每月) (1 - 31)
# | | | .------- 月 (1 - 12) 也可以使用月的英文,例如 jan,feb,mar,apr ...
# | | | | .---- 日期(每周) (0 - 6) (周日即是 0 也是 7 )也可以使用sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * 想要执行命令的用户(这个参数可以为空) 你想要执行的命令
Crontab 一共包含包括 7 个字段,前五个字段是关于设置执行周期的,第六个字段用于指定你想要执行的命令的用户,第七个字段是要执行的命令
在前5个字段中,还可以使用以下的特殊字符
星号 (*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号 (,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠 (-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。
相关的权限文件
- /etc/cron.deny 该文件中所列的用户不允许使用 crontab 命令
- /etc/cron.allow 该文件中所列的用户允许使用 crontab 命令
- /var/spool/cron/ 所有用户 crontab 文件存放的目录,文件名即用户名
Crontab 服务
- 安装 Crontab 服务
CentOS 7.x
yum install crontabs
Fedora 23+
dnf install crontabs
在大多数 Linux 发行版中已经自带的 Crontab ,依旧写一下安装方法
- 启用服务
systemctl start crond
- 停止服务
systemctl stop crond
- 查看服务状态
systemctl status crond
- 加入开机启动
systemctl enable crond
- 取消开机启动
systemctl disable crond
命令格式详解
Usage:
crontab [options] file
crontab [options]
crontab -n [hostname]
Options:
-u <user> define user //设定某个用户的crontab服务,例如,“-u user1”表示设定 user1 用户的 crontab 服务,此参数一般由root用户来运行
-e edit user's crontab //编辑 crontab 文件内容。如果不指定用户,则表示编辑当前用户的crontab文件
-l list user's crontab //显示 crontab 文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容
-r delete user's crontab //删除某个用户的 crontab 文件,如果不指定用户,则默认删除当前用户的crontab文件,此动作一般由 root 来执行
-i prompt before deleting //在删除用户的crontab文件时给确认提示
-n <host> set host in cluster to run users' crontabs //这个选项只有才 cron(8) 才启用,可以根据已经创建好了的配置文件来指定得对于一个集群来执行任务
-c get host in cluster to run users' crontabs //这个选项只有才 cron(8) 才启用,可以查看集群目前的状态,需要和 -n 协同使用
-s selinux context //selinux 相关选项
-x <mask> enable debugging //开启调试
使用方法
- 输入 crontab -e 并回车即可开始编辑当前用户的 crontab 文件,编辑完成保存之后文件立即生效
默认使用 vi 编辑器,如果想要使用 vim 编辑器或者其他编辑器,可以新建环境变量 EDITOR,变量值为你想要使用的编辑器的指令,例如我想要使用 nano 作为编辑器,就可以执行命令 “export EDITOR=nano” 来添加一个环境变量。
如果想要让环境变量永久生效,可以将要执行的命令写入到 “~/.bashrc”中,这样下次启动的时候就会自动配置。
- 如果想要删除 crontab 文件可以使用 crontab -r 来删除当前用户的 crontab 文件
- 想要快速查看 crontab 文件可以使用命令 crontab -l
备份 crontab 文件
为了防止文件被意外删除 , 我们可以在建立好了 crontab 任务之后备份一下相关的配置文件,笔者的思路是在复制一次当期的文档并在后面加上 “.backup” 来示意是备份文件,通常只需要执行以下命令(以 root 用户为例)
cp /var/spool/cron/root /var/spool/cron/root.bachup
如果当前用户没有权限的话,可以先将自己的配置文件复制到自己的 HOME 目录下也是可以的
一些简单的示例
每个月的 1 号的 2:30 分重启 Apache 服务
30 2 1 * * systemctl restart httpd
每个星期的星期一的早上1点重启 mariadb
0 1 * * 1 systemctl restart mariadb
更多的示例可以通过搜索轻松得找到,这里就不多说了
注意事项
通常来说,我们建立的 crontab 任务都是保存了之后立即执行的,但是有的时候却无法执行,将命令单独拿出来却可以使用,这个时候就需要检查一下 crontab 文件的环境变量是否正常。cron 不是 shell,在执行的时候是不知道环境变量的,所以在脚本或者说是配置文件中提供必要的环境变量文件以及路径,主要注意以下几点
- 配置文件中一点涉及路径时,使用绝对路径
- 任务执行需要用到 python 或者 java 又或者其他环境变量的时候,需要通过 source 命令引入环境变量
- 在某些情况下,手动执行脚本可以使用,但是放在 Crontab 中就无法执行,就很有可能是由于环境变量引起的故障,可以通过在 crontab 中直接引入环境变量。
其他事项
- 很奇怪的是在我查阅了很多的资料,发现都说在 crontab 的任务执行完毕之后会向当前系统用户发送一封邮件,但是我的 crontab 在进行了2天的任务都没有接收到任何邮件
- crontab 的文件刚刚写入不一定会立即执行,执行的延迟大概在2分钟左右,如果重启 crond 服务则立即执行
- 据说在 crontab 中 % 是有特殊含义的,表示换行的意思。但是在笔者的验证中没有发现这一现象
- 如果只运行 crontab -r 有可能删除 crontab 目录下的所有用户的 crontab