Linux-定时执行任务
crond 和 crontab 的概念
crond : crond的概念和crontab是不可分割的。crontab是一个命令,常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语chronos(χρόνος),原意是时间。而crond正是它的守护进程。
crontab : 我们经常使用的是crontab命令是cron table的简写,它是cron的配置文件,也可以叫它作业列表,我们可以在以下文件夹内找到相关配置文件。
[root@wqh06 ]# syetemctl start/stop crond # 开启/关闭crond服务
[root@wqh06 ]# systemctl enable/disable crond # 开机自启/关闭crond服务
[root@wqh06 ]# systemctl is-enabled crond # 检查crond服务是否开机自启
crond 服务相关的目录/文件
/var/spool/cron/ 目录
目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名。
[root@wqh06 cron.hourly]# ll /var/spool/cron/
total 0
-rw------- 1 root root 0 Apr 28 09:59 root
-rw------- 1 user01 user01 0 Apr 28 09:46 user01
/etc/cron.d/ 目录
这个目录用来存放任何要执行的crontab文件或脚本;我们还可以把crontab文件及脚本放在
/etc/cron.hourly/
、/etc/cron.daily/
、/etc/cron.weekly/
、/etc/cron.monthly/
目录中,
让它每小时/天/星期、月执行一次。
[root@wqh06 cron.d]# pwd
/etc/cron.d
[root@wqh06 cron.d]# cat crond
* * * * * root /bin/echo "cron.d" >>/tmp/crond # 此位置编辑crontab文件,需要加上用户名
/etc/cron.deny 文件
若想禁用某个用户使用 crond 服务,可以在cron.deny中添加用户名。
[root@wqh06 etc]# echo user01 >> cron.deny
[root@wqh06 etc]# su - user01
Last login: Tue Apr 14 15:09:29 CST 2020 on pts/0
[user01@wqh06 ~]$ crontab -e
You (user01) are not allowed to use this program (crontab)
See crontab(1) for more information
/var/log/cron 文件
记录cron定时任务日志的文件,在调试定时任务时,通常先增加定时任务执行频率(每分钟一次),观察此日志文件内容可知是否报错,实现的功能是否符合期望。
[root@wqh06 cron.hourly]# tailf /var/log/cron -3
Apr 28 10:01:01 wqh06 CROND[7208]: (root) CMD (run-parts /etc/cron.hourly)
Apr 28 10:01:01 wqh06 run-parts(/etc/cron.hourly)[7208]: starting 0anacron
Apr 28 10:01:01 wqh06 run-parts(/etc/cron.hourly)[7217]: finished 0anacron
/etc/crontab 文件
[root@wqh06 etc]# cat crontab
SHELL=/bin/bash // 指定shell 环境(此处默认为 bash shell)
PATH=/sbin:/bin:/usr/sbin:/usr/bin // PATH 变量定义用来执行命令的程序路径
MAILTO=root // cron 任务的输出被邮寄给 MAILTO 变量定义的用户名,如果 MAILTO 变量被定义为空白字符串(MAILTO=""),电子邮件就不会被寄出
# 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
# 此处注释内容为crontab定时任务书写格式,共有六个域,详情见 表-2 crontab时间表示
crondtab 命令
表-1 crontab常用选项及功能
命令 | 功能 |
---|---|
crontab -e | 编辑某个用户的cron服务 |
crontab -l | 列出某个用户cron服务的详细内容 |
crontab -r | 删除某个用户的cron服务 |
crontab -u | 设定某个用户的cron服务 |
表-2 crontab时间表示
项目 | 含义 | 范围 |
---|---|---|
第一个"*" | 一小时当中的第几分钟(minute) | 0~59 |
第二个"*" | 一天当中的第几小时(hour) | 0~23 |
第三个"*" | 一个月当中的第几天(day) | 1~31 |
第四个"*" | 一年当中的第几个月(month) | 1~12 |
第五个"*" | 一周当中的星期几(week) | 0~7(0和7都代表星期日) |
第六个"域" | 需要执行的任务、脚本或命令 | 无 |
表-3 时间特殊符号
特殊符号 | 含义 |
---|---|
*(星号) | 代表任何时间。比如第一个"*"就代表一小时种每分钟都执行一次的意思。 |
,(逗号) | 代表不连续的时间。比如"0 8,12,16* * * 命令"就代表在每天的 8 点 0 分、12 点 0 分、16 点 0 分都执行一次命令。 |
-(中杠) | 代表连续的时间范围。比如"0 5 * * 1-6 命令",代表在周一到周六的凌晨 5 点 0 分执行命令。 |
/(正斜线) | 代表每隔多久执行一次。比如"*/10 * * * * 命令",代表每隔 10 分钟就执行一次命令。 |
表-4 crontab举例(省略命令域)
时间 | 含义 |
---|---|
45 22 * * * | 在 22 点 45 分执行命令 |
0 17 * * 1 | 在每周一的 17 点 0 分执行命令 |
0 5 1,15 * * | 在每月 1 日和 15 日的凌晨 5 点 0 分执行命令 |
40 4 * * 1-5 | 在每周一到周五的凌晨 4 点 40 分执行命令 |
*/10 4 * * * | 在每天的凌晨 4 点,每隔 10 分钟执行一次命令 |
0 0 1,15 * 1 | 在每月 1 日和 15 日,每周一个 0 点 0 分都会执行命令,注意:星期几和几日最好不要同时出现,因为它们定义的都是天,非常容易让管理员混淆 |
定时任务的调试
- 手动执行命令,然后保留执行成功的命令格式
- 编写脚本,脚本统一路径/scripts,脚本的内容要保证正确,减少出错几率(直接复制第一步的命令)
- 执行脚本,使用bash命令执行,命令需要写完全路径(/bin/bash)
- 编写计划任务,需要加上必要的注释信息,作者, 时间,任务
- 增加任务频率调试(每分钟一次),检查环境变量,检查crond服务日志(tailf /var/log/cron)
定时同步时间
在计划定时任务之前,我们需要了解一下
date
命令和ntpdate
命令。
## date命令用法
# 以指定格式输出时间
[root@wqh06 ~]# date +%F
2020-04-29
[root@wqh06 ~]# date +%Y_%m_%d
2020_04_29
[root@wqh06 ~]# date +%T
15:02:25
[root@wqh06 ~]# date +%H_%M_%S
15_03_55
# 指定输出 N天前/N天后 的时间
[root@wqh06 ~]# date +%F -d -10days
2020-04-19
[root@wqh06 ~]# date +%F -d +10days
2020-05-09
## ntpdate命令用法
# 设置固定时间
[root@wqh06 ~]# date -s "2020-11-11"
Wed Nov 11 00:00:01 CST 2020
# 同步阿里云时间
[root@wqh06 ~]# ntpdate ntp.aliyun.com
29 Apr 15:06:13 ntpdate[7009]: step time server 203.107.6.88 offset -16880097.375878 sec
[root@wqh06 ~]# date
Wed Apr 29 15:06:16 CST 2020
# 设置定时执行任务:同步阿里云时间
[root@wqh06 ~]# crontab -e
*/5 * * * * /usr/sbin/ntpdate ntp.aliyun.com >/dev/null 2>&1
实例:定时发送邮件(简历轰炸机)
第一次配置好发送邮箱后,发送邮件给另外一个邮箱时,可能会一直报554错误,而给自己发送就不会报错。
最初我试过网上的解决方案,都不好用,最后手动登录邮箱,给其他邮箱发送一封邮件,再用linux终端发送,就好使了。
## 1.配置服务器发邮件(安装发邮件服务)
[root@wqh06 ~]# yum install -y mailx
## 2.修改mail的配置文件
[root@wqh06 ~]# vim /etc/mail.rc
# 发件人,我的是126邮箱,也可使用163邮箱
set from=xxx@126.com
# 邮件服务器
set smtp=smtp.126.com
# 发件人用户名
set smtp-auth-user=xxx@126.com
# 发件人密码(授权码,从邮箱设置中获取)
set smtp-auth-password=xxxxxxx
# 登录方式
set smtp-auth=login
发送邮件脚本
[root@wqh06 ~]# vim send_resume.sh
#!/bin/bash
resume_dir='/root/resume/'
resume_name=`ls -1 $resume_dir | head -1`
cat $resume_dir/$resume_name | mail -s "zzzwqh的简历" alibaba@163.com
mv $resume_dir/$resume_name /tmp
四个简历
[root@wqh06 resume]# pwd
/root/resume
[root@wqh06 resume]# ll
total 16
-rw-r--r-- 1 root root 2 Apr 26 21:34 resume1
-rw-r--r-- 1 root root 2 Apr 26 21:29 resume2
-rw-r--r-- 1 root root 2 Apr 26 21:29 resume3
-rw-r--r-- 1 root root 2 Apr 26 21:29 resume4
crontab -e
# 每天 8 点投一份简历
00 8 * * * /bin/sh /root/send_resume.sh >/dev/null 2>&1
关于如何获取授权码:
练习
crontab的时间编写规
00 02 * * * ls # 每天的凌晨2点整执行
00 02 1 * * ls # 每月的1日的凌晨2点整执行
00 02 14 2 * ls # 每年的2月14日凌晨2点执行
00 02 * * 7 ls # 每周天的凌晨2点整执行
00 02 * 6 5 ls # 每年的6月周五凌晨2点执行
00 02 14 * 7 ls # 每月14日或每周日的凌晨2点都执行
00 02 14 2 7 ls # 每年的2月14日或每年2月的周天的凌晨2点执行
*/10 02 * * * ls # 每天凌晨2点,每隔10分钟执行一次
* * * * * ls # 每分钟都执行
00 00 14 2 * ls # 每年2月14日的凌晨执行命令
*/5 * * * * ls # 每隔5分钟执行一次
00 02 * 1,5,8 * ls # 每年的1月5月8月凌晨2点执行
00 02 1-8 * * ls # 每月1号到8号凌晨2点执行
0 21 * * * ls # 每天晚上21:00执行
45 4 1,10,22 * * ls # 每月的1,10,22号的4:45执行
45 4 1-10 * * ls # 每月的1到10号的4:45执行
3,15 8-11 */2 * * ls # 每隔两天的上午8点到11点的第3和第15分钟执行
0 23-7/1 * * * ls # 晚上11点到早上7点之间,每隔一个小时执行
15 21 * * 1-5 ls # 周一到周五每天晚上21:15执行