zoukankan      html  css  js  c++  java
  • Linux 定时任务

    at命令:一次性执行定时任务

    at 命令要想正确执行,需要 atd 服务的支持。atd 服务是独立的服务,启动的命令如下:

    [root@localhost ~]# service atd start
    正在启动 atd: [确定]
    如果想让 atd 服务开机时自启动,则可以使用如下命令:
    [root@localhost ~]# chkconfig atd on

     atd 服务启动之后,at 命令才可以正常使用,

     at 命令的访问控制

    这里的访问控制指的是允许哪些用户使用 at 命令设定定时任务,或者不允许哪些用户使用 at 命令。at 命令的访问控制是依靠 /etc/at.allow(白名单)和 /etc/at.deny(黑名单)这两个文件来实现的,具体规则如下: 

    • 如果系统中有 /etc/at.allow 文件,那么只有写入 /etc/at.allow 文件(白名单)中的用户可以使用 at 命令,其他用户不能使用 at 命令(/etc/at.deny 文件会被忽略,也就是说,同一个用户既写入 /etc/at.allow 文件,又写入 /etc/at.deny 文件,那么这个用户是可以使用 at 命令的,因为 /etc/at.allow 文件的优先级更高)。
    • 如果系统中有 /etc/at.allow 文件,那么只有写入 /etc/at.allow 文件(白名单)中的用户可以使用 at 命令,其他用户不能使用 at 命令(/etc/at.deny 文件会被忽略,也就是说,同一个用户既写入 /etc/at.allow 文件,又写入 /etc/at.deny 文件,那么这个用户是可以使用 at 命令的,因为 /etc/at.allow 文件的优先级更高)。
    • 如果系统中没有 /etc/at.allow 文件,只有 /etc/at.deny 文件,那么写入 /etc/at.deny 文件(黑名单)中的用户不能使用 at 命令,其他用户可以使用 at 命令。不过这个文件对 root 用户不生效。
    • 如果系统中这两个文件都不存在,那么只有 root 用户可以使用 at 命令。

    系统中默认只有 /etc/at.deny 文件,而且这个文件是空的,这样系统中所有的用户都可以使用 at 命令。不过,如果我们打算控制用户的 at 命令权限,那么只需把用户写入 /etc/at.deny 文件即可。/etc/at.allow 文件的优先级高,如果 /etc/at.allow 文件存在,则 /etc/at.deny 文件失效。/etc/at.allow 文件的管理更加严格,因为只有写入这个文件的用户才能使用 at 命令,如果需要禁用 at 命令的用户较多,则可以把少数用户写入这个文件。/etc/at.deny 文件的管理较为松散,如果允许使用 at 命令的用户较多,则可以把禁用的用户写入这个文件。不过这两个文件都不能对 root 用户生效。

    at命令

    at 命令的格式非常简单,只需在 at 命令后面加入时间即可,这样 at 命令就会在指定的时间执行。at 命令格式如下:

    [root@localhost ~] # at [选项] 时间

    【选项】

    • -m:当 at 工作宪成后,无论命令是否有输出,都用 E-mail 通知执行 at 命令的用户;
    • -c 工作号: 显示该 at 工作的实际内容;
    【时间】
    • HH:MM 在指定的“小时:分钟”执行命令,如 02:30;
    • HH:MM YYYY-MM-DD 在指定的“小时:分钟 年-月-日”执行命令,如 02:30 2013-07-25;
    • HH:MM[am|pm] [month] [date] 在指定的“小时:分钟[上午|下午][月][日]”执行命令,如 02:30 July 25;
    • HH:MM[am|pm] + [minutes | hours | days | weeks ]在指定的时间“再加多久"执行命令,如 now + 5 minutes, 05am +2 hours;
    at 命令只要指定正确的时间,就可以输入需要在指定时间执行的命令。这个命令可以是系统命令,也可以是 Shell 脚本。 

    定时执行脚本

    [coot@localhost ~]# cat /root/hello.sh
    #!/bin/bash
    echo "hello world!!"
    #该脚本会打印"hello world!!"

    使用 at 定时调用

    [root@localhost ~]# at now +2 minutes
    at> /root/hello.sh >> /root/hello.log
    #执行hello.sh脚本,并把输出写入/root/hello.log文件
    at> <EOT>
    #使用Ctrl+D快捷键保存at任务
    job 8 at 2018-12-16 20:54 #这是第8个at任务,会在2018年12月16日20:54执行

    查询第8个at任务的内容

    [root@localhost ~]# at -c 8
     ...省略部分内容...
    /root/hello.sh >> /root/hello.log
    #可以看到at执行的任务

    在指定的时间关机

    在一个at任务中是可以执行多个系统命令的

    [root@localhost ~J# at 02:00 2018-12-16
    at> /bin/sync
    at> /sbin/shutdown -h now
    at> <EOT>
    job 9 at 2018-12-16 21:00
    在使用系统定时任务时,不论执行的是系统命令还是 Shell 脚本,最好使用绝对路径来写命令,这样不容易报错。at 任务一旦使用 Ctrl+D 快捷键保存,实际上写入了 /var/spool/at/ 这个目录,这个目录内的文件可以直接被 atd 服务调用和执行。

    查询当前服务器上的at任务

    [root@localhost ~]# atq
    9 2018-12-16 2100 a root
    #说明root用户有一个at任务在2018-12-16 21:00 执行,工作号是9

    删除指定的at任务

    [root@localhost ~]# atrm 9
    [root@localhost ~]# atq
    #删除9号at任务,再查询就没有at任务存在了

    crontab命令:循环执行定时任务 

    at 命令仅仅可以在指定的时间执行一次任务,但是系统的定时任务一般是需要重复执行的。所以需要利用 crontab 命令来执行循环定时任务。

    crond服务管理与访问控制

    crontab 命令是需要 crond 服务支持的。crond 服务同样是独立的服务,启动和自启动方法如下:
    [root@localhost ~]# service crond restart
    停止 crond: [确定]
    正在启动 crond: [确定]
    #重新启动crond服务

    设定crond服务为开机自启动

    [root@localhost ~]# chkconfig crond on

    crond 服务默认是自启动的。如果服务器上有循环执行的系统定时任务,就不要关闭 crond 服务了。

    crontab 命令和 at 命令类似,也是通过 /etc/cron.allow 和 /etc/cron.deny 文件来限制某些用户是否可以使用 crontab 命令的。而且原则也非常相似:
    • 当系统中有 /etc/cron.allow 文件时,只有写入此文件的用户可以使用 crontab 命令,没有写入的用户不能使用 crontab 命令。同样,如果有此文件,/etc/cron.deny 文件会被忽略,因为 /etc/cron.allow 文件的优先级更高。
    • 当系统中只有 /etc/cron.deny 文件时,写入此文件的用户不能使用 crontab 命令,没有写入文件的用户可以使用 crontab 命令。
    • 这个规则基本和 at 命令的规则一致,同样是 /etc/cron.allow 文件比 /etc/cron.deny 文件的优先级高,Linux 系统中默认只有 /etc/cron.deny 文件。

    用户的crontab设置

    每个用户都可以实现自己的 crontab 定时任务,只需使用这个用户身份执行“crontab -e”命令即可。当然,这个用户不能写入 /etc/cron.deny 文件。crontab 命令格式如下:
    [root@localhost ~]# crontab [选项]
    [选项]:
    • -e:编辑 crontab 定时任务;
    • -l:查询 crontab 定时任务;
    • -r:删除当前用户所有的 crontab 定时任务。如果有多个定时任务,只想删除一个,则可以使用“crontab -e”;
    • -u 用户名:修改或删除其他用户的 crontab 定时任务。只有 root 用户可用;

    crontab 文件格式 

    crontab 编辑的文件中是通过5个“*”来确定命令或任务的执行时间的,这 5 个“*”的具体含义:

    项目含义范围
    第一个"*" 一小时当中的第几分钟 0~59
    第二个"*" 一天当中的第几小时 0~23
    第三个"*" 一个月当中的第几天 1~31
    第四个"*" 一年当中的第几个月 1~12
    第五个"*" 一周当中的星期几 0~7(0和7都代表星期日)

     在时间表示中,还有一些特殊符号需要学习:

    特殊符号含义
    * 代表任何时间。比如第一个"*"就代表一小时种每分钟都执行一次的意思
    , 代表不连续的时间。比如"0 8,12,16***命令"就代表在每天的8点0分、12点0分、16点0分都执行一次命令
    - 代表连续的时间范围。比如"0 5 ** 1-6命令",代表在周一到周六的凌晨5点0分执行命令
    */n 代表每隔多久执行一次。比如"*/10****命令",代表每隔10分钟就执行一次命令

    当“crontab -e”编辑完成之后,一旦保存退出,那么这个定时任务实际就会写入 /var/spool/cron/ 目录中,每个用户的定时任务用自己的用户名进行区分。而且 crontab 命令只要保存就会生效,只要 crond 服务是启动的。知道了这 5 个时间字段的含义,我们多举几个时间的例子来熟悉一下时间字段,如表 3 所示。

    时间含义
    45 22 *** 命令 在22点45分执行命令
    0 17 ** 1 命令 在每周一的17点0分执行命令
    0 5 1,15** 命令 在每月1日和15日的凌晨5点0分执行命令
    40 4 ** 1-5 命令 在每周一到周五的凌晨4点40分执行命令
    */10 4 *** 命令 在每天的凌晨4点,每隔10分钟执行一次命令
    0 0 1,15 * 1 命令

    在每月1日和15日的0点0分及每周一的0点0分都会执行命令,

    注意:星期几和几日最好不要同时出现,因为定义的都是天,非常容易混淆

    在“执行的任务”字段中既可以定时执行系统命令,也可以定时执行某个 Shell 脚本。 

    让系统每隔 5 分钟就向 /tmp/test 文件中写入一行“11”

    [root@localhost ~]# crontab -e
    #进入编辑界面
    */5 * * * * /bin/echo "11" >> /tmp/test

    如果觉得每隔 5 分钟太长,那就换成“*”,让它每分钟执行一次。而且和 at 命令一样,如果我们定时执行的是系统命令,那么最好使用绝对路径。

    让系统在每周二的凌晨5点05分重启一次

    [root@localhost ~]# crontab -e
    5.5 * * 2 /sbin/shutdown -r now

    如果服务器的负载压力比较大,则建议每周重启一次,让系统状态归零。比如绝大多数游戏服务器每周维护一次,维护时最主要的工作就是重启,让系统状态归零。这时可以让我们的服务器自动来定时执行。

    在每月1日、10日、15 日的凌晨 3 点 30 分都定时执行日志备份脚本 autobak.sh

    [root@localhost ~]# crontab -e
    30.3 11015 * * /root/sh/autobak.sh

    这些定时任务保存之后,就可以在指定的时间执行了。

     查看root用户的crontab任务

    [root@localhost ~]# crontab -l
    */5 * * * * /bin/echo "11" >> /tmp/test
    5.5 * * 2 /sbin/shutdown -r now
    30.3 11015 * * /root/sh/autobak.sh

    删除root用户所有的定时任务

     [root@localhost ~]# crontab -r

    如果只想删除某个定时任务,则可以执行“crontab -e”命令进入编辑模式手工删除

    [root@localhost ~]# crontab -l
    no crontab for root

    删除后,再查询就没有root用户的定时任务了

    crontab的注意事项

    在书写 crontab 定时任务时,需要注意以下几个事项:
    • 6 个选项都不能为空,必须填写。如果不确定,则使用“*”代表任意时间。
    • crontab 定时任务的最小有效时间是分钟,最大有效时间是月。像 2018 年某时执行、3 点 30 分 30 秒这样的时间都不能被识别。
    • 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都以天为单位,非常容易让管理员混淆。
    • 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。

    系统的crontab设置

    “crontab -e”是每个用户都可以执行的命令,也就是说,不同的用户身份可以执行自己的定时任务。但是有些定时任务需要系统执行,这时就需要编辑 /etc/crontab 这个配置文件了。

    当然,并不是说写入 /etc/crontab 配置文件中的定时任务在执行时不需要用户身份,而是“crontab -e”命令在定义定时任务时,默认用户身份是当前登录用户。而在修改 /etc/crontab 配置文件时,定时任务的执行者身份是可以手工指定的。

    [root@localhost ~]# vi /etc/crontab
    SHELL=/bin/bash
    #标识使用哪种Shell
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    #指定PATH环境变量。crontab使用自己的PATH,而不使用系统默认的PATH,所以在定时任务中出现的
    #命令最好使用大写
    MAILTO=root
    #如果有报错输出,或命令结果有输出,则会向root发送信息
    HOME=/
    #标识主目录
    # For details see man 4 crontabs
    #提示大家可以去“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
    #分 时日月周执行者身份命令
    #列出文件格式,并加入了注释

    我们看到 /etc/crontab 中有一句提示,让我们“man 4 crontabs”来查看帮助,在这个帮助中,写明了“在旧版本的 crontab 配置文件中,通过 run-parts 脚本来调用 cron.{daily,weekly,monthly} 目录,定时执行这些目录中的脚本。在当前系统中,为了避免 cron 和 anacron 之间产生冲突,只要 anacron 已经安装,就使用 anacron 来执行这些目录中的脚本。具体可以查看 anacron(8) 的帮助”。  其实,对用户来讲,配置方法都有两种。

    第一种方法就是把需要定时执行的工作写成脚本程序,并赋予执行权限,然后直接把这个脚本复制到 /etc/cron.{daily,weekly,monthly} 目录中的任意一个。比如,我需要让某个脚本每周执行,就把这个脚本复制到 /etc/cron.weekly/ 目录中。这样这个脚本就会每周执行一次,具体的执行时间要参考 anacron 的配置文件。

    第二种方法就是修改 /etc/crontab 这个配置文件,加入自己的定时任务,不过需要注意指定脚本的执行者身份。例如让系统每分钟都执行一次/root/cron/目录中的脚本,脚本执行者是root用户:

    [root@localhost ~]# vi /etc/crontab
    …省略部分输出…
    * * * * * root run-parts /root/cron/

    虽然在CentOS 6.x中不直接通过此配置文件调用/etc/cron.{daily,weekly,monthly}这些目录,但是run-parts脚本还是可以使用的。所以我完全可以参照CentOS 5.x的方法来写定时任务
    使用run-parts脚本调用并执行/root/cron/目录中所有的可执行文件只要保存 /etc/crontab 文件,这个定时任务就可以执行了。当然要确定 crond 服务是运行的。

    [root@localhost ~]# mkdir cron
    #建立/root/cron/目录
    [root@localhost cron]# vi /root/cron/hello.sh
    #/bin/bash
    echo "hello" >> /root/cron/hello.log
    #在/root/cron/hello.log文件中写入“hello”
    [root@localhost cron]# chmod 755 hello.sh
    #赋予执行权限
    #因为hello.sh脚本放入了/root/cron/目录中,所以每分钟执行一次。

    这两种方法都是可以使用的,不过,要想修改 /etc/crontab 文件,必须是 root 用户,普通用户不能修改,只能使用用户身份的 crontab 命令。

    anacron命令 

    在Linux 服务器中,如果不是 24 小时开机的,而刚好在关机的时间段之内有系统定时任务(cron)需要执行,那么这些定时任务是不会执行的。例如:假设我们需要在凌晨 5 点 05 分执行系统的日志备份,但是我们的 Linux 服务器不是 24 小时开机的,在晚上需要关机,在白天上班之后才会再次开机,在这个定时任务的执行时间我们的服务器刚好没有开机,那么这个定时任务就不会执行了。anacron 就是用来解决这个问题的。anacron 会使用 1 天、7 天、一个月作为检测周期,用来判断是否有定时任务在关机之后没有执行。如果有这样的任务,那么 anacron 会在特定的时间重新执行这些定时任务。

    在系统的 /var/spool/anacron/ 目录中存在 cron.{daily,weekly,monthly} 文件,这些文件中都保存着 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 [选项] [参数]

    [选项]:

    • -s:开始执行 anacron 工作,依据 /etc/anacrontab 文件中设定的延迟时间执行;
    • -s:开始执行 anacron 工作,依据 /etc/anacrontab 文件中设定的延迟时间执行;
    • -n:立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间;
    • -u:更新 /var/spool/anacron/cron.{daily,weekly,monthly} 文件中的时间戳,但不执行任何工作;

    [参数]:

    • 工作名:依据 /etc/anacrontab 文件中定义的工作名;

    在当前的 Linux 中,其实不需要执行任何 anacron 命令,只需要配置好 /etc/anacrontab 文件,系统就会依赖这个文件中的设定来通过 anacron 执行定时任务了。这个文件的内容如下:

    [root@localhost ~]# vi /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
    #前面的内容和/etc/crontab类似
    #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_H0URS_RANGE=3-22
    fanacron的执行时间范围是3:00~22:00
    #period in days delay in minutes job-identifier command
    1 5 cron.daily nice run-parts /etc/cron.daily
    7 25 cron.weekly nice run-parts /etc/cron.weekly
    ©monthly 45 cron.monthly nice run-parts /etc/cron.monthly
    #天数 强制延迟(分) 工作名称 实际执行的命令
    #当时间差超过天数时,强制延迟多少分钟之后就执行命令

    在这个文件中,“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 配置文件即可。

    比如,让定时任务在凌晨 03:00-05:00 执行,就可以进行如下修改:

    [root@localhost ~] # vi /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_HOORS_RANGE=3-5
    #执行时间范围为03:0005: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分钟,不再强制廷迟

    这样,所有放入 /etc/cron.{daily,weekly,monthly} 目录中的脚本都会在指定时间执行,而且也不怕服务器万一关机的情况了。

  • 相关阅读:
    checkbox美化
    JS 之简单计算器
    python实现简单用户认证和角色制授权
    搭建高性能web服务
    纯JS实现fadeIn 和fadeOut
    纯CSS实现气泡框
    javascript之对象(二)&& 继承问题
    JavaScript之对象(一)
    Web发展史
    [LeetCode 256] Paint House
  • 原文地址:https://www.cnblogs.com/lizhouwei/p/10127340.html
Copyright © 2011-2022 走看看