1 定时任务介绍
1.1 定时任务含义和用途
# 含义
设定某个日期或时间周期性执行指令
比如设定一个闹铃,叫你每天早上7点钟起床等
# 用途
定期备份数据,定期执行脚本程序
1.2 什么是Crond?
# Crond是Linux系统中用来定期执行命令或脚本的一种服务软件
一般情况下,安装完CentOS操作系统之后,默认便会启动Crond任务调度服务 # 一个守护进程
Crond服务会定期检查系统中是否有要执行的任务工作 # 默认每分钟检查一次
如果有,便会根据其预先设定的定时任务规则,自动执行该定时任务工作
1.3 定时任务分类
# 1.系统任务调度 (系统级别的定时任务)
临时文件清理例/tmp和/var/tmp等、系统信息采集、日志文件切割、写缓存数据到硬盘、日志清理等
# 2.用户任务调度 (用户级别的定时任务)
定时向互联网同步时间、定时备份系统配置文件、定时备份数据库的数据
2 定时任务管理
2.1 系统级 计划任务
### 方式一:编辑文件 /etc/crontab 系统任务调度的配置文件
[root@localhost ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
51 * * * * root run-parts /etc/cron.hourly
24 7 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
# 配置解读:
# 1.配置部分:前四行用来配置crond任务运行的环境变量
SHELL : 系统执行的采用哪个shell
PATH : 系统执行命令的路径
MAILTO : 指定crond的任务执行信息将通过电子邮件发送给root用户
若值为空,则表示不发送任务执行信息给用户
HOME : 指定在执行命令或者脚本时使用的主目录
# 2.运行部分:
详见计划任务语法格式
### 方式二:把脚本放到该目录下 常用
/etc/cron.hourly/ # 每小时运行该目录里的内容
/etc/cron.daily/ # 每天运行该目录里的内容
/etc/cron.weekly/ # 每周运行该目录里的内容
/etc/cron.monthly/ # 每月运行该目录里的内容
2.2 用户级 计划任务
### 1 用户使用 crontab 工具来定制自己的计划任务
yum install crontabs # 安装crontab
/sbin/service crond start # 启动服务
/sbin/service crond stop # 关闭服务
/sbin/service crond restart # 重启服务
/sbin/service crond reload # 重新载入配置
/sbin/service crond status # 查看服务状态
ntsysv # 查看是否开机启动
chkconfig –level 35 crond on # crontab加入开机自动启动
### 2 文件目录的含义
文件:/etc/cron.deny # 该文件中所列用户 不允许使用crontab命令
文件:/etc/cron.allow # 该文件中所列用户 允许使用crontab命令
目录:/var/spool/cron/ # 所有用户crontab文件存放的目录,分别以用户名命名
eg:/var/spool/cron/root
文件:/var/log/cron # crond日志文件
### 3 crontab 基本命令
# 1.编辑计划任务
crontab -e # 编辑 当前用户的crontab文件
crontab -u egon -e # 编辑 指定用户的crontab文件
# 2.查看计划任务
crontab -l # 查看当前用户的crontab文件
# 3.删除计划任务
crontab -r # 删除当前用户的crontab文件
# 4.查看日志
tail /var/log/cron
# 5.将某个用户添加为黑名单
echo "egon" >> /etc/cron.deny
2.3 计划任务语法格式
# 前提强调:crond是按照分钟进行计算的,不支持秒
* 表示任意的(分、时、日、月、周)时间都执行
- 表示一个时间段 整数范围 eg: 5-7点 表示 5、6、7
, 表示分隔时段 列表范围 eg: 6,0,4 表示 周六、日、四
/1 表示每隔n单位时间 间隔频率 eg: */10 表示 每10分钟执行一次 0-23/2 表示每两小时执行一次
定时任务crontab的编写规范
00 02 * * * # 每天 凌晨2点整执行
00 02 1 * * # 每月的1日 凌晨2点整执行
00 02 14 2 * # 每年的2月14日 凌晨2点执行
00 02 * * 7 # 每周天 凌晨2点整执行
00 02 * 6 5 # 每年的6月周五 凌晨2点执行
00 02 14 * 7 # 每月14日或每周日 凌晨2点都执行
00 02 14 2 7 # 每年的2月14日或每年2月的周天 凌晨2点执行
*/10 02 * * * # 每天凌晨2点,每隔10分钟执行一次
* * * * * # 每分钟都执行
*/5 * * * * # 每隔5分钟执行一次
00 02 * 1,5,8 * # 每年的1月5月8月 凌晨2点执行
00 02 1-8 * * # 每月1号到8号 凌晨2点执行
45 4 1,10,22 * * # 每月1、10、22日 4:45执行
45 4 1-10 * * # 每月1到10日 4:45执行
3,15 8-11 */2 * * # 每隔两天的上午8点到11点的第3和第15分钟执行
0 23-7/2 * * * # 每天晚上11点到早上7点之间,每隔两小时执行
15 21 * * 1-5 # 周一到周五每天晚上 21:15执行
3 定时任务实例
3.1 实操经验总结
# 9句箴言
1.定时任务规则之前加注释
2.使用脚本执行定时任务
# 只有一条简单命令的可以直接使用命令执行
3.运行脚本一定要用绝对路径执行,统一脚本位置
4.定时任务中date命令的百分号 需转义 才能使用
5.命令或脚本结果(正确及错误)定向到空(>/dev/null 2>&1) 或 追加到文件中 >>/tmp/oldboy.txt 2>&1
6.避免不必要的程序及命令输出,如打包命令,tar -v的显示过程的选项
7.打包压缩使用相对路径 # 切到目标目录的上一级打包目标
8.定时任务脚本中的程序文件,尽量用绝对路径
# 用户的定时任务中的文件,默认存放在当前用户的家目录
9.系统与命令位置有关的环境变量问题,建议脚本中重新定义环境变量PATH
3.2 定时任务编写思路
# 1.手动执行命令,然后保留执行成功的结果
# 2.编写脚本
脚本需要统一路径/scripts
脚本内容复制执行成功的命令(减少每个环节出错几率)
# 3.执行脚本
使用bash命令执行, 防止脚本没有增加执行权限(/usr/bin/bash /bin/bash)
执行脚本成功后,复制该执行的命令,以便写入cron
# 4.编写定时任务
加上必要的注释信息:人、时间、任务
设定定时任务执行的周期
粘贴执行脚本的命令(不要手敲)
# 5.调试定时任务
增加任务频率测试
检查环境变量问题 # 最好在脚本中重新定义环境变量PATH
检查crond服务日志
3.3 常见crontab不执行的问题
# 第一、脚本的原因
大多数情况下,就是脚本的问题,概率占到70%以上
因为程序执行到某一步导致crontab终止执行
eg: 碰到一次在迁移代码的时候将数据库连错了,导致无法访问而死在那里了。
# 第二、执行环境问题
当我们碰到第一情况下,一般都可以通过手动执行程序将问题扼杀在摇篮里
问题是当我们 手动执行成功而crontab不能执行的时候
eg: 相关路径的设置问题。
解决方案:在代码最前面执行 source /home/user/.bash_profile
# 第三、系统时间问题
这种问题最好理解,也是比较常见和隐蔽的问题
解决方案:date -s
# 第四、脚本权限问题
必须保证执行脚本的用户,有执行改文件的权限
# 第五、进程问题
crontab守护进程死掉了。极少发生的,但也不排除,当我们实在是找不到其他原因的时候可以用
解决方案:重启该进程
# 第六、无理由
crontab不执行的问题困扰了好长时间,脚本写的都正确,但是就是不执行
解决方案:重新加载root用户的任务列表,并重启服务
crontab -u root /var/spool/cron/root
systemctl restart crond # 重启服务
# 第七、服务启动问题
crond没有启动
解决方案:service crond start
# 第八、脚本编码问题
脚本在window下编写,传到linux下后报“锘?!/bin/bash”
解决方案:用vi编辑器新建新shell脚本,输入内容后保存
# 第九 date命令的百分号 转义问题
* * * * * tar czf /tmp/`date '+%Y'` /etc
该计划任务中命令的执行流程是crond->tar命令
而crond在执行tar命令时,无法识别通配符%的意思(shell能识别),所以该命令无法正常执行
解决方案:* * * * * tar czf /tmp/`date '+\%Y'` /etc
通常都会把要执行的操作放到文件中
然后/bin/bash a.sh去执行
* * * * * /bin/bash a.sh
这样的执行流程就变成了 crond->bash shell->a.sh
这样a.sh内即便是写%号,也能被识别出来