• Linux学习-53-定时任务管理(at、anacron命令)


    12.19 at命令详解:定时执行任务
    • 使用 at 命令,需提前安装好 at 软件包,并开启 atd 服务。因此,首先来看看如何安装 at 软件包。在 Linux 系统中,查看 at 软件包是否已安装,可以使用 rpm -q 命令,如下所示:
    [root@CncLucZK ~]# rpm -q at
    at-3.1.20-11.el8.x86_64
    
    
    • 1
    • 2
    • 3
    • 可以看到,当前系统已经安装 at 软件包,若所用系统未安装,可使用如下命令进行安装:
    [root@localhost ~]# yum -y install at
    Redirecting to /bin/systemctl start atd.service
    #省略输出信息,最终出现 Complete!,证明安装成功。
    
    • 1
    • 2
    • 3
    • 除此之外,at 命令要想正确执行,还需要 atd 服务的支持。atd 服务是独立的服务,启动的命令如下:
    [root@localhost ~]# service atd start
    正在启动 atd: [确定]
    
    • 1
    • 2
    • 如果想让 atd 服务开机时自启动,则可以使用如下命令:
    [root@localhost ~]# chkconfig atd on
    
    • 1

    当然,独立服务的自启动也可以修改 /etc/rc.local 配置文件.

    • 安装好 at 软件包并开启 atd 服务之后,at 命令才可以正常使用,不过在此之前,我们还要学习一下 at 命令的访问控制

    • 访问控制:指的是允许哪些用户使用 at 命令设定定时任务,或者不允许哪些用户使用 at 命令。大家可以将其想象成设定黑名单或白名单,这样更容易理解。

    • at 命令的访问控制是依靠 /etc/at.allow(白名单)和 /etc/at.deny(黑名单)这两个文件来实现的,具体规则如下:

      • 如果系统中有 /etc/at.allow 文件,那么只有写入 /etc/at.allow 文件(白名单)中的用户可以使用 at 命令,其他用户不能使用 at 命令(注意,/etc/at.allow 文件的优先级更高,也就是说,如果同一个用户既写入 /etc/at.allow 文件,又写入 /etc/at.deny 文件,那么这个用户是可以使用 at 命令的)。
      • 如果系统中没有 /etc/at.allow 文件,只有 /etc/at.deny 文件,那么写入 /etc/at.deny 文件(黑名单)中的用户不能使用 at 命令,其他用户可以使用 at 命令。不过这个文件对 root 用户不生效。
      • 如果系统中这两个文件都不存在,那么只有 root 用户可以使用 at 命令。
    • 系统中默认只有 /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用户不受这两个文件的控制
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 这个实验说明了 /etc/at.allow 文件的优先级更高,如果 /etc/at.allow 文件存在,则 /etc/at.deny 文件失效。/etc/at.allow 文件的管理更加严格,/etc/at.deny 文件的管理较为松散,因为只有写入这个文件的用户才能使用 at 命令,如果需要禁用 at 命令的用户较多,则可以把少数用户写入这个文件。不过这两个文件都不能对 root 用户生效。

    • at 命令的格式非常简单,基本格式如下:

    [root@localhost ~] # at [选项] [时间] 回车 >执行命令
    
    • 1
    • 常用的几个选项及各自含义如表 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执行的任务
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    [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任务中是可以执行多个系统命令的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 在使用系统定时任务时,不论执行的是系统命令还是 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任务存在了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    12.21 Linux检测长期未执行的定时任务(anacron命令)
    • 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 [选项] [工作名]
    
    • 1
    • 这里的工作名指的是依据 /etc/anacrontab 文件中定义的工作名。此命令常用的几个选项及各自的功能:
    选项功能
    -f强制执行相关工作,忽略时间戳。
    -u更新 /var/spool/anacron/cron.{daily,weekly,monthly} 文件中的时间戳为当前日期,但不执行任何工作。
    -s依据 /etc/anacrontab 文件中设定的延迟时间顺序执行工作,在前一个工作未完成前,不会开始下一个工作。
    -n立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间。
    -q禁止将信息输出到标准错误,常和 -d 选项合用。
    • 当前的 Linux 中,其实不需要执行任何 anacron 命令,只需要配置好 /etc/anacrontab 文件,系统就会依赖这个文件中的设定来通过 anacron 执行定时任务了。那么,关键就是 /etc/anacrontab 文件的内容了。这个文件的内容如下:
    [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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 在这个文件中,“RANDOM_DELAY”定义的是最大随机延迟,也就是说,cron.daily 工作如果超过 1 天没有执行,则并不会马上执行,而是先延迟强制延迟时间,再延迟随机延迟时间,之后再执行命令;“START_HOURS_RANGE”的是定义 anacron 执行时间范围,anacron 只会在这个时间范围内执行。

    • 用 cron.daily 工作来说明一下 /etc/anacrontab 的执行过程:

      1. 读取 /var/spool/anacron/cron.daily 文件中 anacron 上一次执行的时间。
      2. 和当前时间比较,如果两个时间的差值超过 1 天,就执行 cron.daily 工作。
      3. 只能在 03:00-22:00 执行这个工作。
      4. 执行工作时强制延迟时间为 5 分钟,再随机延迟 0~45 分钟。
      5. 使用 nice 命令指定默认优先级,使用 run-parts 脚本执行 /etc/cron.daily 目录中所有的可执行文件。
    • 然后发现,/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分钟,不再强制廷迟
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 这样,所有放入 /etc/cron.{daily,weekly,monthly} 目录中的脚本都会在指定时间执行,而且也不怕服务器万一关机的情况了。

    参考文献:
    Linux at命令详解:定时执行任务

    下一篇:Linux学习-54-循环执行定时任务(crontab命令)
  • 相关阅读:
    Leetcode DAY14: 递归遍历 and 迭代遍历 and 统一迭代
    做个清醒的程序员之拥抱AI
    SpringBoot整合MongoDB
    MySQL事务详解
    Nacos原理简单介绍
    Linux | 进程终止与进程等待
    order by、limit注入
    mvcc机制中的快照读和当前读
    关于产研项目管理的一些思考与记录
    canal rocketmq
  • 原文地址:https://blog.csdn.net/weixin_42045639/article/details/128000180