1.1 一次性计划任务 at

at 工具

  • 由 at 软件包提供设置计划任务命令,其中软件包还提供 batch命令,系统自行选择空闲时间去执行此处指定的任务。

  • at 执行任务时PATH变量的值和当前定义任务的用户身份一致

  • at 计划任务依赖于atd.service 服务,有atd.service监控时间,定时执行at计划的任务。

    [root@centos7 ~ ]# yum install -y at
    [root@centos7 ~ ]# systemctl is-active atd.service
    active

at 计划任务简单示例

#查看当前时间
[root@centos7 ~ ]# date
Fri Jun 18 17:07:46 CST 2021
​
#at命令创建计划任务格式:at <时间>
[root@centos7 ~ ]# at 17:30
at> echo "at Schedule a task"
at> touch /tmp/at.log
at> <EOT>                             # at一个计划任务支持设置多条命令,ctrl + D 退出at
job 3 at Fri Jun 18 17:30:00 2021     # 创建计划任务信息
​
#查看at 创建计划任务
[root@centos7 ~ ]# at -l
4   Fri Jun 18 17:30:00 2021 a root
​
# at 创建计划任务会在对应/var/spool/at目录下创建定时脚本
[root@centos7 ~ ]# ll /var/spool/at/
-rwx------ 1 root root 2631 Jun 18 17:09 a00004019d01ba
drwx------ 2 root root    6 Jun 18 16:55 spool

注意一下几点

  1. at创建计划任务相当于创建一个脚本,存放在 /var/spool/at目录下

  2. 计划任务会以创建计划任务的用户身份执行,也就是用户环境变量在执行at 计划变量值是一致的

  3. 在执行at计划任务,执行命令有输出和错误信息误以执行任务的用户身份发邮件通知给 root,所以系统上需要邮件服务postfix

# centos 8 最小化默认需要安装
yum install -y postfix
systemctl start --now postfix
​
# 邮件查看
[root@centos7 ~ ]# mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 1 message
>   1 root                  Fri Jun 18 17:30  15/509   "Output from your job        4"
& 1
Message  1:
From root@centos7.localdomain  Fri Jun 18 17:30:00 2021
Return-Path: <root@centos7.localdomain>
X-Original-To: root
​
at Schedule a task

at命令常用参数

参数

含义

at -l

查看at命令创建的计划任务;相当于 atq

at -d <任务编号>

删除指定编号计划任务;相当于 atrm

at -c <任务编号>

查看指定编号的任务;相当于cat /var/spool/at/目录下对应脚本文件

at -f <文件> <时间>

at命令接收标准输入信息,即:从指定文件中读取任务

at -m

当任务被完成之后,将给用户发送邮件,即使没有标准输出

at -t <时间>

定义时间格式

at 计划任务创建方式

  1. 交互式创建计划任务

  2. 标准输入重定向方式

    [root@centos7 ~ ]# echo "wall welcome to china" |at 17:29
  3. at -f 读取指定文件

    [root@centos7 ~ ]# echo "wall welcome to china" > at.txt
    [root@centos7 ~ ]# at -f at.txt 17:29

at 命令定义计划任务时间格式

#第一种:年月日时分,不能精确到秒钟
# HH:MM YYYY-MM-DD   规定在某年某月的某一天的特殊时刻进行该项任务
at 02:00 2020-7-1
​
#第二种:noon(中午);midnight(晚上);4pm(下午4点);tomorrow(明天)
at 06pm March 17        # 3月17号下午6对点
at 17:20 tomorrow       # 明天的17点20分
​
#第三种:在某个时间点再加几个时间后才进行该项任务
# HH:MM[am|pm] + number [minutes|hours|days|weeks]
at now + 5 min      # 当前时间5分钟后执行
at 2pm + 3 days     # 3天后的下午2点

控制用户是否能执行at任务

  • 白名单:/etc/at.allow 默认不存在,手动创建此文件后,只有文件中存在用户才能创建计划任务,否则其他用户没有权限执行at命令。

  • 黑名单:/etc/at.deny 默认存在,拒绝该文件中用户执行at命令

  • 如果两个文件都不存在,只有 root 可以执行 at 命令,其他用户将没有权限支持at命令。

[test@centos7 ~ ]$ at -l
You do not have permission to use at.

1.2 周期性计划任务 cron

周期性任务计划cron相关的程序包

  • cronie 主程序包,提供编写计划任务工具crontab;以及cron计划任务的服务 crond.service,用于监控时间执行任务。

  • crontabs 软件包,提供系统计划任务,以及run-parts工具(run-parts工具作用是:把指定目录下可执行文件全部执行)

  • cronie-anacron 软件包,cronie的检查程序,用于监控cronie任务执行状况,如:cronie中的任务在过去该运行的时间点未能正常运行,则anacron会随后启动一次此任务

cron依赖于crond服务,确保crond服务处于运行状态,其功能是监控时间到点执行任务

systemctl status crond

cron计划任务分为俩种

  • 系统计划任务:系统维护作业,/etc/crontab 主配置文件, /etc/cron.d/ 子配置文件

  • 用户计划任务:保存在 /var/spool/cron/USERNAME,利用 crontab 命令管理

crond定义的计划任务输出信息和错误信息,会以mail邮件形式告知通过向定义计划任务用户。

计划任务日志:/var/log/cron

1.2.1 cron 系统计划任务

系统计划任务主配置文件/etc/crontab详细说明,只有root用户可编辑。

查看帮助:man 5 crontab

[root@centos7 ~ ]# vim /etc/crontab
SHELL=/bin/bash                       #执行计划任务使用的shell类型
PATH=/sbin:/bin:/usr/sbin:/usr/bin    #默认的PATH变量搜索命令路径,可修改
MAILTO=root                           #cron会把执行任务的输出信息和错误信息通过mail邮件告知用户,此处指定告知的用户
​
#编写系统计划任务格式
# 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
​
第一个星号表示:每多少分钟后执行任务,范围是 0 ~ 59
第二个星号表示:每多少小时后执行任务,范围是 0 ~ 23
第三个星号表示:每多少天后执行任务,范围是 1 ~ 31 ,但主要以月份决定,比如:2月没有30天
第四个星号表示:时间到达指定月份执行任务,范围是 1 ~ 12,也可英文简写 jan,feb,mar,apr ...
第五个星号表示:日期到达指定星期执行任务,范围是 0 ~ 6 , 0表示周日,6表示周六
user-name   指定执行此任务的用户
command     执行任务
​
#注意点:指定的日期天数 和 指定星期几属于或关系(man 5 crontab 查看)
30 4 1,15 * 5       将导致在每个月的1号和15号加上每个周五的凌晨4:30运行一个命令

计划任务时间格式

语法一:给定时间点有效取值范围内的值

05 02 * * * <COMMAND>           #每小时的第5分钟执行一次任务
30 02 * * * <COMMAND>           #每天的凌晨2点30分执行一次任务
30 16 * * * <COMMAND>           #每天的16点30分执行一次任务

语法二:以星号表示时间

* * * * * <COMMAND>         #每隔一分钟执行一次任务
*/5 * * * * <COMMAND>       #每隔5分钟执行一次任务
*/5 */5 * * * <COMMAND>     #每隔5小时的一小时内,每个5分钟执行一次任务。即:5点 10点 15点 20点
*/5 12  * * * <command>     #每天的12点的每5分钟执行一次任务

语法三:给定多个时间点

5,10,30 * * * * <COMMAND>       #每个小时的第5分钟,第10分钟,第30分钟执行一次任务
5,10,30 10,14 * * * <COMMAND>   #每天的10点的第5分钟,第10分钟,第30分钟执行一次任务 和 14点的第5分钟,第10分钟,第30分钟执行一次任务

语法四:给定一个连续时间点

10-20 * * * * <COMMAND>         #每个小时的第10分钟到第20分钟内,每隔一分钟执行一次任务
10-50/5 * * * * <COMMAND>       #每个小时的第10分钟到第50分钟内,每隔5分钟执行一次任务

语法五:cron关键字

@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       #重启后执行一次

1.2.2 cron 系统计划任务相关文件

cron系统计划任务相关文件,来自于cetontabs软件包

/etc/crontab            #cron编写系统计划任务主文件
/etc/cron.d/            #cron编写系统计划任务子文件
/etc/cron.hourly/       #每小时执行目录下存放的可执行文件
/etc/cron.daily/        #每天执行目录下存放的可执行文件
/etc/cron.weekly/       #每周执行目录下存放的可执行文件
/etc/cron.monthly/      #每月执行目录下存放的可执行文件

/etc/crontab文件为crond系统计划任务主配置,其中也可以把一个计划任务单独存放/etc/cron.d/目录下,避免误修改主配置文件内容

#此目录只能root用户编辑
[root@centos7 ~ ]# ll -d /etc/cron.d
drwxr-xr-x. 2 root root 21 Jun 18 18:16 /etc/cron.d 
​
#/etc/cron.d/目录下存在一个模板文件
[root@centos7 ~ ]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly      #每个小时的第一分钟执行/etc/cron.hourly目录下可执行文件
​
#自定义计划任务文件
[root@centos7 ~ ]# cat /etc/cron.d/test
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
MAILTO=root
* * * * * demouser echo $PATH

/etc/anacrontab配置文件说明

anacrontab程序是对cronie计划任务是否执行进行检查,对笔记本电脑、台式机、工作站、偶尔要关机的服务器及其它不一直开机的系统很重要对很有用。假如定义了一个凌晨2点备份数据的计划任务,但是凌晨2点时刻服务器宕机了则无法执行规定时间内的计划任务,anacron 会以 1 天、1周(7天)、一个月作为检测周期,判断是否有定时任务在关机之后没有执行。如果有这样的任务,那么 anacron 会在特定的时间重新执行这些定时任务

配置文件:/etc/anacrontab,负责执行/etc/ cron.daily /etc/cron.weekly /etc/cron.monthly中系统任务,内容如下

[root@centos7 ~ ]# cat /etc/anacrontab
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那就执行
1   5   cron.daily      nice run-parts /etc/cron.daily
#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被执行,就会执行
7   25  cron.weekly     nice run-parts /etc/cron.weekly
#每隔一个月开机后 45 分钟检查 /etc/cron.monthly 目录内的文件是否被执行,如果一个月内没有被执行,那就执行 
@monthly 45 cron.monthly        nice run-parts /etc/cron.monthly
​
#定义anacrontab补救计划任务的延时时间,也就是说:定义开机5分钟后开始计划任务补救,最迟是 5 + 45分钟执行补救的计划任务
RANDOM_DELAY=45
#定义一个时间段,假设计划任务在此时间段为执行,则由anacrontab程序求救,也就是说:0-2点 和 23-24点内没有执行计划任务,anacrontab不会补救
START_HOURS_RANGE=3-22

1.2.3 cron 用户计划任务

crontab命令

  • 每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME

  • 默认标准输出和错误会被发邮件给对应的用户,如:testuser创建的任务就发送至testuser的邮箱

  • root能够修改其它用户的作业 ,普通用户只能修改自己的计划任务。

  • 用户的cron 中默认 PATH=/usr/bin:/bin,如果使用其它路径,在任务文件的第一行定义PATH路径

  • 计划任务执行脚本需要执行权限。

crontab命令参数

参数

含义

crontab -e

调用vi编辑器,编写用户计划任务

crontab -l

查看用户的计划任务

crontab -r

删除全部用户计划任务

crontab -i

同-r一同使用,以交互式模式移除指定任务

crontab -u <用户> [ -e | -l | -r | -i ]

仅root可运行,指定用户管理cron任务

crontab默认调用vi编辑器,编写内容不带颜色,可以自定义调用的编辑器

[root@centos7 ~ ]# cat /etc/profile.d/PS1.sh
#定义系统编辑文件内容调用的编辑器
export EDITOR=vim

注意点:使用crontab创建计划任务,默认PATH=/usr/bin:/bin,比如一些root管理员命令放置在/usr/sbin目录下,修改如下:可以crontab -e 的第一行指定PATH路径,或者使用命令绝对路径。

[root@centos7 ~ ]# crontab -e
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

面试题:11月每天的6-12点之间每隔2小时执行/app/bin/test.sh

0 6-12/2 * 11 * /app/bin/test.sh

示例:每隔10分钟检查系统磁盘占比情况,超过预设值则报警

[root@centos7 ~ ]# cat check_disk.sh
#!/bin/bash
WARNING=10
df | sed -En '/^\/dev/s#([^ ]+).* ([0-9]+)%.*#\1 \2#gp' | while read DEVICE USE;do
    [ $USE -gt $WARNING ] && echo "$DEVICE WILL BE FULL, USE: $USE" | mail -s disk_full root
done
​
[root@centos7 ~ ]# chmod +x check_disk.sh
[root@centos7 ~ ]# crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
*/10 * * * * /root/check_disk.sh

1.2.4 cron 计划任务注意点

注意点一:

cron任务中不建议使用%,crontab命令中的 % 会被当成回车来看待,而且 % 后的内容会作为该命令的标准输入;如果在命令中要使用%,则需要用 \ 转义 或者写入脚本中 ;将%放置于单引号中是不支持的

#错误写法
30 2 * * * /bin/cp -a /etc/ /data/etc`date +%F_%T`
​
#正确写法
30 2 * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`
​
#crontab中将把%后面内容作为前面命令的标准输入
* * * * * bc % 2+1

注意二:

运行结果的标准输出和错误以邮件通知给相关用户,尽量把无用信息重定向垃圾箱文件中/dev/null,避免产生大量邮件文件

注意三:

无论是cron计划任务还是at计划任务,以分钟执行任务,无法实现以秒级别运行任务;方法如下:利用sleep命令实现以秒级别运行任务

sleep 20;echo "hihi"

计划任务也无法完成以每7分钟执行任务,原因是一个小时60分钟无法被7整除;方法也是利用sleep命令

sleep 20s       #sleep命令默认以秒级别
sleep 5m        #进程休眠5分钟
sleep 3h        #进程休眠3个小时
sleep 2d        #进程休眠2天

usleep命令:以微秒级的休眠

#休眠一微秒
usleep 100000
sleep 0.000001
​
#休眠一毛秒
usleep 1000
sleepp 0.0001