[root@CncLucZK ~]# rpm -q at
at-3.1.20-11.el8.x86_64
[root@localhost ~]# yum -y install at
Redirecting to /bin/systemctl start atd.service
#省略输出信息,最终出现 Complete!,证明安装成功。
[root@localhost ~]# service atd start
正在启动 atd: [确定]
[root@localhost ~]# chkconfig atd on
当然,独立服务的自启动也可以修改 /etc/rc.local 配置文件.
安装好 at 软件包并开启 atd 服务之后,at 命令才可以正常使用,不过在此之前,我们还要学习一下 at 命令的访问控制。
访问控制:指的是允许哪些用户使用 at 命令设定定时任务,或者不允许哪些用户使用 at 命令。大家可以将其想象成设定黑名单或白名单,这样更容易理解。
at 命令的访问控制是依靠 /etc/at.allow(白名单)和 /etc/at.deny(黑名单)这两个文件来实现的,具体规则如下:
系统中默认只有 /etc/at.deny 文件,而且这个文件是空的,因此,系统中所有的用户都可以使用 at 命令。不过,如果我们打算控制用户的 at 命令权限,那么只需把用户写入 /etc/at.deny 文件即可。
[root@CncLucZK ~]# ll -l /etc/at*
-rw-r--r--. 1 root root 1 May 11 2019 /etc/at.deny
#系统中默认只有at.deny文件
[root@CncLucZK ~]# echo zk >> /etc/at.deny #把zk用户写入/etc/at.deny文件
[root@CncLucZK ~]# su - zk
Last login: Tue Oct 25 23:04:23 CST 2022 on pts/0
[zk@CncLucZK ~]$ at 01:00
You do not have permission to use at. #没有权限使用at命令,切换成zk用户,这个用户已经不能执行at命令了
[zk@CncLucZK ~]$ exit
logout
[root@CncLucZK ~]# echo zk >> /etc/at.allow #建立/etc/at.allow文件,并在文件中写入zk用户
[root@CncLucZK ~]# su - zk
Last login: Wed Oct 26 00:37:12 CST 2022 on pts/1
[zk@CncLucZK ~]$ at 01:00
warning: commands will be executed using /bin/sh
at> #切换成zk用户zk用户可以执行at命令。这时zk用户既在/etc/at.deny文件中,又在/etc/at.allow文件中,但是/etc/at.allow文件的优先级更高
^C
[zk@CncLucZK ~]$ exit
logout #返回root身份
[root@CncLucZK ~]# at 01:00
warning: commands will be executed using /bin/sh
at>
#root用户虽然不在/etc/at.allow文件中,但是也能执行at命令,
#root用户虽然不在/etc/at.allow文件中,但是也能执行at命令,
#说明root用户不受这两个文件的控制
这个实验说明了 /etc/at.allow 文件的优先级更高,如果 /etc/at.allow 文件存在,则 /etc/at.deny 文件失效。/etc/at.allow 文件的管理更加严格,/etc/at.deny 文件的管理较为松散,因为只有写入这个文件的用户才能使用 at 命令,如果需要禁用 at 命令的用户较多,则可以把少数用户写入这个文件。不过这两个文件都不能对 root 用户生效。
at 命令的格式非常简单,基本格式如下:
[root@localhost ~] # at [选项] [时间] 回车 >执行命令
常用的几个选项及各自含义如表 1 所示。
选项 | 含义 |
---|---|
-m | 当 at 工作完成后,无论命令是否输出,都用 E-mail 通知执行 at 命令的用户。 |
-c 工作标识号 | 显示该 at 工作的实际内容。 |
-t 时间 | 在指定时间提交工作并执行,时间格式为 [[CC]YY]MMDDhhmm。 |
-d | 删除某个工作,需要提供相应的工作标识号(ID),同 atrm 命令的作用相同。 |
-l | 列出当前所有等待运行的工作,和 atq 命令具有相同的额作用。 |
-f 脚本文件 | 指定所要提交的脚本文件。 |
关于时间参数可用的以下格式。
格式 | 用法 |
---|---|
HH:MM | 比如 04:00 AM。如果时间已过,则它会在第二天的同一时间执行。 |
Midnight(midnight) | 代表 12:00 AM(也就是 00:00)。 |
Noon(noon) | 代表 12:00 PM(相当于 12:00)。 |
Teatime(teatime) | 代表 4:00 PM(相当于 16:00)。 |
英文月名 日期 年份 | 比如 January 15 2018 表示 2018 年 1 月 15 号,年份可有可无。 |
MMDDYY、MM/DD/YY、MM.DD.YY | 比如 011518 表示 2018 年 1 月 15 号。 |
now+时间 | 以 minutes、hours、days 或 weeks 为单位,例如 now+5 days 表示命令在 5 天之后的此时此刻执行。 |
at 命令只要指定正确的时间,就可以输入需要在指定时间执行的命令。这个命令可以是系统命令,也可以是 Shell 脚本。举几个例子。
[coot@CncLucZK ~]# cat /test/hello.sh
#!/bin/bash
echo "hello world!!"
#该脚本会打印"hello world!!"
[root@CncLucZK ~]# at now +2 minutes
at> /test/hello.sh >> /test/hello.log
#执行hello.sh脚本,并把输出写入/test/hello.log文件
at>
#使用Ctrl+D快捷键保存at任务
job 8 at 2013-07-25 20:54 #这是第8个at任务,会在2013年7月25日20:54执行
[root@CncLucZK ~]# at -c 8
#查询第8个at任务的内容
...省略部分内容...
#主要定义系统的环境变量
/test/hello.sh >> /test/hello.log
#可以看到at执行的任务
[root@localhost ~J# at 02:00 2013-07-26
at> /bin/sync
at> /sbin/shutdown -h now
at>
job 9 at 2013-07-26 02:00
#在指定的时间关机。在一个at任务中是可以执行多个系统命令的
在使用系统定时任务时,不论执行的是系统命令还是 Shell 脚本,最好使用绝对路径来写命令,这样不容易报错。at 任务一旦使用 Ctrl+D
快捷键保存,实际上写入了 /var/spool/at/ 这个目录,这个目录内的文件可以直接被 atd 服务调用和执行。
atq 命令和 atrm 命令。atq 命令用于查看当前等待运行的工作,atrm 命令后者用于删除指定的工作,它们的使用方法也很简单,这里给大家举几个简单的例子。
[root@CncLucZK ~]# atq
2 Wed Oct 26 01:00:00 2022 a root
#说明root用户有一个at任务在2022-10-26日01:00执行,工作号是2
[root@CncLucZK ~]# atrm [工作号]
#删除指定的at任务
[root@CncLucZK ~]# atrm 9
[root@CncLucZK ~]# atq
#删除2号at任务,再查询就没有at任务存在了
anacron: 会以 1 天、1周(7天)、一个月作为检测周期,判断是否有定时任务在关机之后没有执行。如果有这样的任务,那么 anacron 会在特定的时间重新执行这些定时任务。anacron 是如何判断这些定时任务已经超过执行时间的呢?这就需要借助 anacron 读取的时间记录文件。anacron 会分析现在的时间与时间记录文件所记载的上次执行 anacron 的时间,将两者进行比较,如果两个时间的差值超过 anacron 的指定时间差值(一般是 1 天、7 天和一个月),就说明有定时任务没有执行,这时 anacron 会介入并执行这个漏掉的定时任务,从而保证在关机时没有执行的定时任务不会被漏掉。
在 CentOS 6.x 中,使用 cronie-anacron 软件包取代了 vixie-cron 软件包。而且在原先 CentOS 版本的 /etc/cron.{daily,weekly,monthly} 目录中的定时任务会同时被 cron 和 anacron 调用,这样非常容易出现重复执行同一个定时任务的错误。因此,在 CentOS 6.x 中,/etc/cron.{daily,weekly,monthly} 目录中的定时任务只会被 anacron 调用,从而保证这些定时任务只会在每天、每周或每月定时执行一次,而不会重复执行。不仅如此,在 CentOS 6.x 中,anacron 还有一个变化,那就是 anacron 不再是单独的服务,而变成了系统命令。也就是说,我们不再使用“service anacron restart”命令来管理 anacron 服务了,而需要使用 anacron 命令来管理 anacron 工作。
anacron命令的基本格式如下:
[root@localhost ~]# anacron [选项] [工作名]
选项 | 功能 |
---|---|
-f | 强制执行相关工作,忽略时间戳。 |
-u | 更新 /var/spool/anacron/cron.{daily,weekly,monthly} 文件中的时间戳为当前日期,但不执行任何工作。 |
-s | 依据 /etc/anacrontab 文件中设定的延迟时间顺序执行工作,在前一个工作未完成前,不会开始下一个工作。 |
-n | 立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间。 |
-q | 禁止将信息输出到标准错误,常和 -d 选项合用。 |
[root@CncLucZK test]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
#最大随机廷迟,单位:分钟
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#fanacron的执行时间范围是3:00~22:00
#period in days delay in minutes job-identifier command
#每天开机 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
在这个文件中,“RANDOM_DELAY”定义的是最大随机延迟,也就是说,cron.daily 工作如果超过 1 天没有执行,则并不会马上执行,而是先延迟强制延迟时间,再延迟随机延迟时间,之后再执行命令;“START_HOURS_RANGE”的是定义 anacron 执行时间范围,anacron 只会在这个时间范围内执行。
用 cron.daily 工作来说明一下 /etc/anacrontab 的执行过程:
然后发现,/etc/cron.{daily,weekly,monthly} 目录中的脚本在当前的 Linux 中是被 anacron 调用的,不再依靠 cron 服务。不过,anacron 不用设置多余的配置,我们只需要把需要定时执行的脚本放入 /etc/cron.{daily,weekly,monthly} 目录中,就会每天、每周或每月执行,而且也不再需要启动 anacron 服务了。如果需要进行修改,则只需修改 /etc/anacrontab 配置文件即可。
例如让定时任务在凌晨 01:00-03:00 执行,就可以进行如下修改:
[root@CncLucZK test]# vi /etc/anacron
cat: /etc/anacron: No such file or directory
[root@CncLucZK test]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=0 #把最大随机廷迟改为0分钟,不再随机廷迟
# the jobs will be started during the following hours only
START_HOURS_RANGE=1-3 #执行时间范围为03:00—05:00
#period in days delay in minutes job-identifier command
1 0 cron.daily nice run-parts /etc/cron.daily
7 0 cron.weekly nice run-parts /etc/cron.weekly
@monthly 0 cron.monthly nice run-parts /etc/cron.monthly
#把强制延迟也改为0分钟,不再强制廷迟
参考文献:
Linux at命令详解:定时执行任务