Linux本身带有任务计划功能,通过配置,可以让服务器在固定的时间周期里面执行我们预先写好的脚本或者命令。不用每次手动执行,实现自动化运维,再也不用半夜起床手动备份网站数据了。任务计划分为一次性任务和周期性任务。
实现计划任务之前必须安装并启动邮件服务,因为输出的结果会邮件通知用户。
Centos
yum -y install postfix
systemctl enable --now postfix
Ubuntu
apt -y install mailutils
systemctl enable --now postfix
一次性任务at
at 工具:
- 由包 at 提供
- 依赖与atd服务,需要启动才能实现at任务
- at队列存放位置 Centos: /var/spool/at | Ubuntu:/var/spool/cron/atjobs
- 执行任务时PATH变量的值和当前定义任务的用户身份一致
at 命令:
at [option] TIME
常用选项:
-V 显示版本信息
-t time 时间格式 [[CC]YY]MMDDhhmm[.ss]
-l 列出指定队列中等待运行的作业;相当于atq
-d N 删除指定的N号作业;相当于atrm
-c N 查看具体作业N号任务
-f file 指定的文件中读取任务
-m 当任务被完成之后,将给用户发送邮件,即使没有标准输出
时间格式:
HH:MM 在今日的 HH:MM 进行,若该时刻已过,则明天此时执行任务
02:00
HH:MM YYYY-MM-DD 规定在某年某月的某一天的特殊时刻进行该项任务
02:00 2016-09-20
HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow
HH:MM[am|pm] + number [minutes|hours|days|weeks], 在某个时间点再加几个时间后才进行该项任务
now + 5 min
02pm + 3 days
at任务的执行方式有三种:
- 交互式
- 输入重定向
- at -f file 配置文件控制用户是否能执行at任务
- 白名单:/etc/at.allow 默认不存在,只有该文件中的用户才能执行at命令
- 黑名单:/etc/at.deny 默认存在,拒绝该文件中用户执行at命令,而没有在at.deny 文件中的使用者则可执行
- 如果两个文件都不存在,只有 root 可以执行 at 命令
周期性任务cron
系统cron任务:
系统维护作业,/etc/crontab 主配置文件, /etc/cron.d/ 子配置文件。
用户cron任务:
保存在 /var/spool/cron/USERNAME(ubuntu 系统存放在/var/spool/cron/crontabs/USERNAME),利用 crontab 命令管理。
系统cron计划任务
/etc/crontab 格式说明,详情参见 man 5 crontab。
注释行以 # 开头
run-parts会自动执行文件夹里的所有脚本
test -x判断文件是否可执行,可执行为true
SHELL=/bin/bash #默认的SHELL类型
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin #默认的PATH变量值,可修改为其它路径
# 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
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
计划任务时间表示法:
(1) 特定值
给定时间点有效取值范围内的值
(2) *
给定时间点上有效取值范围内的所有值,表示“每...”,放在星期的位置表示不确定
(3) 离散取值
#,#,#
(4) 连续取值
#-#
(5) 在指定时间范围上,定义步长
/#: #即为步长
(6) 特定关健字
@yearly 0 0 1 1 *
@annually 0 0 1 1 *
@monthly 0 0 1 * *
@weekly 0 0 * * 0
@daily 0 0 * * *
@hourly 0 * * * *
@reboot Run once after reboot
文档里面对于日期和星期几字段的关系的解释:
如果同时设定了日和星期几,那么这两个条件只要满足其中一个,都会执行计划任务。
例如,”30 4 1,15 * 5″ 表示,每个月的(1号15号再加上周五)的4:30执行计划任务。
Note: The day of a command's execution can be specified by two fields — day of month, and day of week. If both fields are restricted (i.e., don't start with *),the command will be run when either field matches the current time. For example,''30 4 1,15 * 5'' would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday. One can, however, achieve the desired result by
adding a test to the command (see the last example in EXAMPLE CRON FILE below).
crond任务相关文件:
/etc/crontab 配置文件
/etc/cron.d/ 配置文件
/etc/cron.hourly/ 脚本
/etc/cron.daily/ 脚本
/etc/cron.weekly/ 脚本
/etc/cron.monthly/ 脚本
用户计划任务crontab
crontab命令:
- 每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME /var/spool/cron/crontabs/USERNAME
- 默认标准输出和错误会被发邮件给对应的用户,如:frog创建的任务就发送至frog的邮箱
- root能够修改其它用户的作业
- 用户的cron 中默认 PATH=/usr/bin:/bin,如果使用其它路径,在任务文件的第一行加PATH=/path或者加入到计划任务执行的脚本中
- 第六个字段指定要运行的命令。该行的整个命令部分,直至换行符或“%”字符,指定的shell执行。除非使用反斜杠(\)进行转义,否则该命令中的“%”字符将变为换行符,并且第一个%之后的所有数据将作为标准输入发送到该命令。
crontab命令格式:
crontab [-u user] [-l | -r | -e] [-i]
常用选项:
-l 列出所有任务
-e 编辑任务
-r 移除所有任务
-i 同-r一同使用,以交互式模式移除指定任务
-u user 指定用户管理cron任务,仅root可运行
控制用户执行计划任务:
/etc/cron.{allow,deny}
如何修改默认的cron的文本编辑工具:
vim /etc/profile.d/env.sh
#往文件里添加以下内容
export EDITOR=vim
给计划任务配置PATH变量的两种方式
方法1:直接在计划任务的文件里加上PATH变量
crontab -e
#在最上面添加PATH变量后保存,PATH变量的值根据需要自己设定,以下仅供参考
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
方法2:在脚本中指定PATH变量
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
crontab会将运行结果的标准输出和错误以邮件通知给相关用户,建议把标准输出和错误都扔到垃圾桶里,避免邮箱爆炸。
* * * * * COMMAND &> /dev/null
如果修改了时区,任务还是不能准时执行,需要重启crond服务和rsyslog服务
systemctl restart crond
systemctl restart rsyslog
在11月25日的21点16分关闭nginx服务的计划任务写法
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
16 21 25 11 * systemctl stop nginx &> /dev/null