1 计划任务
通过计划任务, 可以让系统自动的按时间或周期性执行任务
未来的某时间点执行一次任务
at 指定时间点, 执行一次性任务
batch 系统自行选择空闲时间去执行此处指定的任务
周期性运行某任务
cron
2 一次性任务
at工具:
- 包at提供
- 依赖于atd服务, 需要启动后才能实现at任务
- at队列存放在/var/spool/at目录中
- 执行任务时PATH变量的值和当前定义任务的用户身份一致
at命令:
at [option] TIME
常用选项:
-v 显示版本信息
-t time 时间格式 [[CC]YY]MMDDhhmm[.ss]
-l 列出指定队列中等待运行的作业: 相当于atq命令
-d 删除指定的作业, 相当于atrm命令
-c 查看具体作业任务
-f /path/file 从指定的文件中读取任务
-m 当任务被完成之后, 将给用户发送邮件, 即使没有标准输出也发
注意:
作业执行命令的结果中的标准输出和错误以执行任务的和用户身份发邮件给root用户, 并不会打印在终端上, 因为计划任务是未来某个时间点执行的, 而系统不确定用户在那个时间点是否还会使用终端
因此, 计划任务中的命令最好不要有输出, 避免发送大量的邮件给root用户
默认CentOS 8最小化安装没有安装邮件服务, 需要自行安装
[22:59:45 root@CentOS-8-1 ~]#yum -y install postfix
[01:18:56 root@CentOS-8-1 ~]#systemctl enable --now postfix
TIME: 定义什么时候进行at这项任务的时间
HH:MM [YYYY-mm-dd]
noon, midnight, teatime(4pm)
tomorrow
now+#{minutes, hours, days, OR weeks}
案例: at时间格式
HH:MM 在今日的 HH:MM 进行, 若该时刻已过, 则明天相同时间执行此任务
02:00
HH:MM YYYY-MM-DD 规定在某年某月的某一天的特殊时刻进行该项任务
02:00 2040-04-04
HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow
HH:MM[am|pm] + number [minutes|housrs|days|weeks] 在某个时间点再加几个时间后才进行该项任务
now + 5 min
02pm + 3 days
at任务执行方式:
交互式
输入重定向
at -f file
- 交互式执行at任务
[01:40:56 root@centos-7-1 ~]#at 1:42
at> echo 'haha'
at> <EOT> # 要按ctrl + d退出
job 3 at Fri Feb 5 01:42:00 2021
创建的计划任务会存到/var/spool/at/下对应的文件里, 执行后删除
[01:43:01 root@centos-7-1 ~]#ls /var/spool/at/
a00004019a11e9 spool
- 输入重定向
[01:51:48 root@centos-7-1 ~]#echo 'haha' | at now+1min
job 6 at Fri Feb 5 01:53:00 2021
[01:52:11 root@centos-7-1 ~]#at now+1min << EOF
> wall haha
> EOF
job 7 at Fri Feb 5 01:54:00 2021
at任务执行权限控制:
利用/etc/at.{allow,deny}控制用户是否能执行at任务
白名单机制: /etc/at.allow 默认不存在, 只有该文件中的用户才能执行at命令
黑名单机制: /etc/at.deny 默认存在, 拒绝该文件中用户执行at命令, 而没有在at.deny文件中的使用者则可以执行at命令
如果两个文件都不存在, 那么只有root用户可以执行at命令
如果某个用户在两个文件都存在, 那么白名单生效
3 周期性计划任务 cron
周期性计划任务cron相关的程序包
cronie: 主程序包. 提供crond守护进程及相关辅助工具
crontabs: 包含CentOS提供的系统维护任务
cronie-anacron: cronie的补充程序, 用于监控cronie任务执行状况, 如: cronie中的任务在过去该运行的时间点未能正常运行, 则anacron会随后启动一次此任务
cron依赖于crond服务, 需要确保crond守护进程处于运行状态
[01:30:43 root@centos-7-1 ~]#systemctl status crond
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-02-04 16:35:39 CST; 8h ago
cron任务分为:
系统cron任务: 系统维护作业, /etc/crontab 主配置文件, /etc/cron.d/ 子配置文件, root用户才能创建
用户cron任务: 保存在/var/spool/cron/USRNAME, 利用crontab命令管理, 普通用户也可以
计划任务日志: /var/log/cron
3.1 系统 cron 计划任务
/etc/crontab
vim /etc/crontab
SHELL=/bin/bash 默认的SHELL类型
PATH=/sbin:/bin:/usr/sbin:/usr/bin 默认的PATH变量值, 可修改为其他路径
MAILTO=root 默认标准输出和错误输出邮件发给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
计划任务时间表示方法:
1. 特定值: 给定时间点有效取值范围内的值 5 2 1 2 1 二月份的每周的周一和第一天的2点05
2. * 给定时间点上有效取值范围内的所有值, 表示每... * * * * * 每个月每天每小时每分钟
3. 离散取值 * * * * 1,2,3 周一周二周三
4. 连续取值 * * * * 1-6 周一到周六
5. 在指定时间范围内, 定义步长
/#, 表示每... 例如: 0 */2 * * * 每2小时执行一次, 当定义了小时级别的整点任务, 分钟可以写0, 表示整点.
案例
每晚9点10分运行echo命令
10 21 * * * root /bin/echo 'haha'
每3小时执行一次echo和wall命令
0 */3 * * * root /bin/echo 'haha'; wall 'hehe' # 多个任务用";"隔开
注意: 如果day和week都制定了时间, 那么都会运行
3.2 用户计划任务
crontab命令
每个用户都有专用的cron任务文件: /var/spool/cron/USERNAME
默认标准输出和错误会被发送邮件给对应的用户
root能够修改其他用户的作业
用户的cron中默认的 PATH=/usr/bin:/bin, 如果使用其他路径, 在任务文件的第一行加PATH=/path或者加入到计划任务执行的脚本中
常用选项
-l 列出所有任务
-e 编辑任务
-r 移除所有任务
-i 同-r一同使用, 以交互式模式移除指定任务
-u user 仅root可运行, 指定用户管理cron任务
修改默认的crontab的编辑工具
默认crontab用vi, 没有颜色提示, 可以添加EDITOR变量
vim /etc/profile.d/env.sh
export EDITOR=vim
控制用户执行计划任务权限
原理同at一样
/etc/cron.{allow,deny}
控制计划任务的PATH变量
方法1: 在计划任务配置中指定PATH
[03:05:46 root@centos-7-1 ~]#crontab -l
PATH=/usr/local/sbin
0 */3 * * * /bin/echo 'haha'; /usr/bin/wall 'hehe' # 用户计划任务不用写用户名, 因为本身就是以某个用户执行的crontab -e
方法2: 在运行的脚本中定义PATH变量
#!/bin/bash
PATH=/usr/local/bin
echo 'haha'
案例: 11月每天的6-12点之间每个2小时执行/app/bin/test.sh
6-12/2 表示6-12点之间/每2小时, 也就是6,8,10,12
0 6-12/2 * 11 * /app/bin/test.sh
运行结果的标准输出和错误输出会以邮件通知用户, 需要将命令的结果重定向
CMD $> /dev/null
cron任务中不建议用%, 因为其表示换行, 且第一个%后的所有字符串会被当作命令的标准输入
如果在命令中要使用%, 则需要'\'转义
将%放在单引号是不支持的
28 3 * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`
28 3 * * * /bin/cp -a /etc/ /data/etc`date +'%F_%T'` 不支持
案例: 如何运行秒级别的计划任务
计划任务不支持秒级任务, 只能用循环, 配合sleep实现, 比如健康性检查
vim sec.sh
while true; do
echo `date +%F_%T >> /opt/echo.log`
sleep 1
done
chmod +x sec.sh
nohup ./sec.sh &> /dev/null &
实现每7分钟运行1次任务
利用sleep命令
[03:59:29 root@centos-7-1 ~]#while :; do date +%F_%T; sleep 3s; done # 每三秒执行任务
2021-02-05_03:59:50
2021-02-05_03:59:53
sleep选项
s: 秒
m: 分钟
h: 小时
d: 天
案例: 每周的工作日1:30, 将/etc备份到/backup目录, 保存的文件名称为""etcbak-yyyy-mm-dd-HH.tar.xz
30 1 * * 1-5 /usr/bin/tar Jcf /backup/etcbak-`date +%F-%H`.tar.xz /etc &> /dev/null
案例: 每两小时取出当前系统/proc/meminfo文件中以S或M开头的信息, 追加到/tmp/meminfo.txt文件中
0 */2 * * * grep -E '^S|^M' /proc/meminfo >> /tmp/meminfo.txt
案例: 工作日时间, 每10分钟执行一次磁盘空间检查, 一旦发现任何分区利用率高于80%, 就执行wall警报
网友评论