Linux20--定时任务之:crond计划任务

1 定时任务介绍

1.1 定时任务含义和用途

# 含义
设定某个日期或时间周期性执行指令

比如设定一个闹铃,叫你每天早上7点钟起床等


# 用途
定期备份数据、定期执行脚本程序、服务器巡检

1.2 什么是Crond?

# Crond是Linux系统中用来定期执行命令或脚本的一种服务软件  

一般情况下,安装完CentOS操作系统之后,默认便会启动Crond任务调度服务  # 一个守护进程

Crond服务会定期检查系统中是否有要执行的任务工作  # 默认每分钟检查一次
如果有,便会根据其预先设定的定时任务规则,自动执行该定时任务工作

1.3 定时任务分类

# 1.系统任务调度 (系统级别的定时任务)
临时文件清理 eg:/tmp和/var/tmp等、系统信息采集、日志文件切割、写缓存数据到硬盘、日志清理等

# 2.用户任务调度 (用户级别的定时任务)
定时向互联网同步时间、定时备份系统配置文件、定时备份数据库的数据
### eg:临时文件清理脚本
vim tmp_clearup.sh   # 删除/tmp目录下 7天前的文件
find /tmp -type f -mtime +7 -exec rm -f {} ;


### eg:系统信息(内存)采集脚本
vim mem_check.sh
#!/bin/bash
mem_total=`free -m | awk 'NR==2 {print $2}'`
mem_used=`free -m | awk 'NR==2 {print $3}'`
mem_free=`free -m | awk 'NR==2 {print $4}'`
mem_used_rate=`free -m | awk 'NR==2 begin{printf "%.2f%\n",($3/$2)*100n}'`
echo '---- mem check info ----'
echo "总内存:$mem_total"
echo "已使用:$mem_used"
echo "还剩余:$mem_free"
echo "使用率:$mem_used_rate"



### eg: 日志切割脚本   每天12点,将messages日志文件,进行切割(复制、重命名)
vim messages_log_slice.sh
#!/bin/bash
cp /var/log/messages /var/log/messages-$(date +%Y%m%d -d '-1 day')
> /var/log/messages   # 清空


### eg:同步时间脚本
ntpdate  # 需要外网

2 定时任务管理

2.1 系统级 计划任务

### 方式一:编辑文件 /etc/crontab   系统任务调度的配置文件

[root@localhost ~]# cat /etc/crontab 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# 系统级别定时任务命令
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
# run-parts命令,可以执行一个目录下所有的可执行文件,但目录下文件必须有执行权限


# 配置解读:
# 1.配置部分:前四行用来配置crond任务运行的环境变量
SHELL  : 系统执行的采用哪个shell
PATH   : 系统执行命令的路径  环境变量
MAILTO : 指定crond的系统任务执行信息将通过电子邮件发送给root用户
         若值为空,则表示不发送任务执行信息给用户
HOME   : 指定在执行命令或者脚本时使用的主目录

# 2.运行部分:
分 时 日  月  周  用户名 执行命令
  # 时间及特俗符合:详见2.3 计划任务语法格式  


### 方式二:把脚本放到该目录下    常用
/etc/cron.hourly/  # 每小时运行该目录里的内容

/etc/cron.daily/   # 每天运行该目录里的内容

/etc/cron.weekly/  # 每周运行该目录里的内容

/etc/cron.monthly/ # 每月运行该目录里的内容

2.2 用户级 计划任务

### 1 用户使用 crontab 工具来定制自己的计划任务

yum install crontabs  # 安装crontab

/bin/systemctl start crond   # 启动服务
/bin/systemctl stop crond    # 关闭服务
/bin/systemctl restart crond # 重启服务
/bin/systemctl reload  crond # 重新载入配置
/bin/systemctl enable crond  # 开机启动
/bin/systemctl status crond  # 查看服务状态


### 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 --f /var/log/cron  # -f 循环读取 文件里的最尾部的内容显示在屏幕上,并且不断刷新

# 5.将某个用户添加为黑名单
echo "egon" >> /etc/cron.deny 

2.3 计划任务语法格式

# 前提强调:crond是按照分钟进行计算的,不支持秒


### 语法格式: 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
              用户名      执行的命令


### 特殊符号:
*    表示任意的(分、时、日、月、周)时间都执行

-    表示一个时间段 整数范围  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 编写思路

# 1.手动执行命令,然后保留执行成功的结果

# 2.编写脚本
  脚本 统一放某个路径下 /scripts/
  脚本内容复制执行成功的命令(减少每个环节出错几率)
  脚本执行的输出信息可以重定向至其他位置保留或写入/dev/null

# 3.执行脚本    
  使用bash命令执行, 防止脚本没有增加执行权限(/usr/bin/bash /bin/bash)
  执行脚本成功后,复制该执行的命令,以便写入cron
  

# 4.编写定时任务
  加上必要的注释信息:人、时间、任务
  设定定时任务执行的周期
  粘贴执行脚本的命令(不要手敲)

# 5.调试定时任务
  增加任务频率测试
  检查环境变量问题  # 最好在脚本中重新定义环境变量PATH
  检查crond服务日志 /var/log/cron

3.2 经验总结

# 9句箴言
1.定时任务规则之前加注释

2.使用脚本执行定时任务
  # 只有一条简单命令的可以直接使用命令执行

3.运行脚本的命令,一定要用绝对路径执行
  统一脚本位置  # 脚本常放在 /scripts/
  # eg: /usr/local/bin/docker

4.定时任务中date命令的百分号 需转义 才能使用

5.命令或脚本结果(正确及错误)定向到空( &>/dev/null ) 或 追加到指定 文件中 &>>/tmp/oldboy.txt
  # 当程序在所指定的时间执行后,系统会发一封邮件给当前的用户( 用户邮件文件:/var/spool/mail/用户 ),显示该程序执行的内容

6.避免不必要的程序及命令输出
  # eg: 打包命令,tar -v的显示过程的选项

7.打包压缩使用相对路径  # 切到目标目录的上一级 打包目标

8.定时任务脚本中的程序文件,尽量用绝对路径
  # 用户的定时任务中的文件,默认存放在当前用户的家目录

9.系统与命令位置有关的环境变量问题,建议脚本中重新定义环境变量PATH

3.3 常见crontab不执行的问题

# 第一、脚本的原因
大多数情况下,就是脚本的问题,概率占到70%以上
因为程序执行到某一步导致crontab终止执行 

eg: 碰到一次在迁移代码的时候将数据库连错了,导致无法访问而死在那里了。


# 第二、执行环境问题
问题是当我们 手动执行成功而crontab不能执行的时候

eg: 相关路径的设置问题。
解决方案:

1. 在 定时任务脚本中,重新加载下环境变量
#!/bin/sh
. /etc/profile    
. ~/.bash_profile  或 source /home/user/.bash_profile

2.在 /etc/crontab 中添加环境变量,在可执行命令之前添加命令 . /etc/profile; 使得环境变量生效
eg: 20 03 * * * . /etc/profile;/bin/sh /var/www/runoob/test.sh


# 第三、系统时间问题
这种问题最好理解,也是比较常见和隐蔽的问题

解决方案:date -s 


# 第四、脚本权限问题
必须保证执行脚本的用户,有执行改文件的权限


# 第五、进程问题
crontab守护进程死掉了。极少发生的,但也不排除,当我们实在是找不到其他原因的时候可以用

解决方案:重启该进程
systemctl start crond

# 第六、无理由
crontab不执行的问题困扰了好长时间,脚本写的都正确,但是就是不执行

解决方案:重新加载root用户的任务列表,并重启服务
crontab -u root /var/spool/cron/root
systemctl restart crond  # 重启服务

# 第七、脚本编码问题
脚本在window下编写,传到linux下后报“锘?!/bin/bash”
解决方案:用vi编辑器新建新shell脚本,输入内容后保存


# 第八、date命令的百分号 转义问题
* * * * * tar czf /tmp/`date '+%Y'` /etc 
该计划任务中命令的执行流程是 crond->tar命令
而crond在执行tar命令时,无法识别通配符%的意思(shell能识别),所以该命令无法正常执行

解决方案:* * * * * tar czf /tmp/`date '+\%Y'` /etc
通常都会把要执行的操作放到 a.sh 脚本文件中
然后/bin/bash a.sh去执行
* * * * * /bin/bash a.sh
这样的执行流程就变成了 crond->bash shell->a.sh
这样a.sh脚本文件内即便是写%号,也能被识别出来

4 定时任务示例

4.1 使用root用户每5分钟执行一次时间同步

# 1.测试同步时间命令
ntpdate time.windows.com


# 2.查看命令目录
which ntpdate 
  /usr/sbin/ntpdate   
  # 发现在/etc/crontab 中 PATH里,可执行命令,但最好路径全加上


# 3.配置定时任务
crontab -e -u root
# 每五分钟执行一次时间同步
*/5 * * * * ntpdate time.windows.com &>/dev/null

4.2 每天凌晨3点做一次备份

### 要求:
1.将/etc/目录进行打包,备份到/backup下面
2.文件名要求格式:hostname_ip_2018-02-20_etc.tar.gz
3.只保留最近3天的数据
4.在执行计划任务时,不要输出任务信息
5.验证文件是否完整     
6.将验证结果发送到邮箱
7.每天凌晨3.50执行该备份


### 1 定时脚本
vim /root/bak.sh
# 每天凌晨3:50 备份/etc目录
#!bin/bash
# 1.重新定义环境变量
# export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin 

# 2.定义变量
hostname=`hostname`
date=`date +%F`
ip=`hostname -I | awk '{print $1}'`

# 3.创建备份目录
mkdir /backup

# 4.备份打包
cd /
tar -czf backup/${hostname}_${ip}_${date}_etc.tar.gz /etc   

# 5.删除超过三天的备份包
find /backup/ -type f -name "*.tar.gz" -mtime +3 |  xargs rm -rf

# 6.利用md5sum 校验文件一致性
# 将报文(得到加密字符串),并输出给flag.txt
md5sum /backup/${hostname}_${ip}_${date}_etc.tar.gz > /backup/flag.txt  

# 校验文件一致性
md5sum -c /backup/flag.txt  # 注意:校验文件和报文在同一个目录下
  :确定



### 2 添加定时任务
crontab -e

50 3 * * * /bin/bash /root/bak.sh &>/dev/null
posted @   Edmond辉仔  阅读(83)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示