Linux系统定时任务

    科技2022-07-12  144

    文章目录

    一、at 一次性执行定时任务1. at 服务管理与访问控制2. at 命令3. 其他at管理命令 二、crontab 循环执行定时任务1. crontab 服务管理与访问控制2. crontab 命令时间常用举例crontab 的注意事项 3. 系统的crontab 设置anacron

    一、at 一次性执行定时任务

    1. at 服务管理与访问控制

    查看 at 软件包是否已安装

    [root@localhost ~]$ rpm -a at

    没有安装就通过yum方式安装

    [root@localhost ~]$ yum install 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. 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用户生效。

    2. at 命令

    语法格式:

    [root@localhost ~]$ at [选项] 时间 at 命令选项及含义 选项含义-m当 at 工作完成后,无论命令是否输出,都用 E-mail 通知执行 at 命令的用户。-c 工作标识号显示该 at 工作的实际内容。-t 时间在指定时间提交工作并执行,时间格式为 [[CC]YY]MMDDhhmm。-d删除某个工作,需要提供相应的工作标识号(ID),同 atrm 命令的作用相同。-l列出当前所有等待运行的工作,和 atq 命令具有相同的额作用。-f 脚本文件指定所要提交的脚本文件。 at 命令时间参数可用格式 格式用法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命令只要指定正确的时间,就可以输入需要在指定时间执行的命令了,这个命令可以是系统命令,也可以是shel1脚本。举几个例子吧:

    例子1:

    [root@localhost ~]$ at 23:30 #设置一次性任务 at > systemctl restart httpd #要执行的命令 at > #此处请同时按下 Ctrl + D 组合键来结束编写计划任务 job 3 at Mon Apr 27 23:30:00 2020 [root@localhost ~]$ at -l #查看已设置好但还未执行的一次性计划任务 [root@localhost ~]$ atrm 任务序号 #删除定时任务 #可以让 at 命令接收前面 echo 命令的输出信息,以达到通过非交互式的方式创建计划一次性任务的目的 [root@localhost ~]$ echo "systemctl restart httpd" | at 23:30 job 4 at Mon Apr 27 23:30:00 2020 [root@localhost ~]$ at -l 3 Mon Apr 27 23:30:00 2017 a root 4 Mon Apr 27 23:30:00 2017 a root

    例子2:

    [root@localhost ~]$ cat /root/hello.sh #!/bin/bash echo "hello wor1d!!" #该脚本会打印“hello workd! ! ” [root@localhost ~]$ at now +2 minutes at>/root/hello.sh >>/root/he1lo.log #执行hello sh_脚本,并把输出写入/root/hello.log文件 at> <EOT> #使用ctrl+d 保存at 任务 job 8 at 2018-07-25 20:54 #这是第8个at任务,会在2018年7月25日20:54分执行 [root@localhost ~]$ at -c 8 #查询第8个at 任务的内容 …省略部分内容… #主要是定义系统的环境变量 /root/hello. sh >>/root/hello.log #可以看到at执行的任务

    例子3:

    [root@localhost ~]$ at 02:00 2013-07-26 at> /bin/sync at> /sbin/shutdown -h now at> <EOT> job 9 at 2013-07-26 02:00 #在指定的时间关机。在一个at任务中是可以执行多个系统命令的

    在使用系统定时任务时,不论执行的是系统命令还是 Shell 脚本,最好使用绝对路径来写命令,这样不容易报错。at 任务一旦使用 Ctrl+D 快捷键保存,实际上写入了 /var/spool/at/ 这个目录,这个目录内的文件可以直接被 atd 服务调用和执行。

    3. 其他at管理命令

    atq 命令用于查看当前等待运行的工作,atrm 命令后者用于删除指定的工作 例子1:atq 命令的用法

    [root@localhost ~]$ atq 9 2020-07-26 02:00 a root #说明root用户有一个at任务在2020年7月26日02:00执行,工作号是9 [root@localhost ~]$ atrm [工作号] #删除指定的at任务

    :例 2:atrm 命令的用法

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

    二、crontab 循环执行定时任务

    1. crontab 服务管理与访问控制

    查看 crontab 软件包是否已安装

    [root@localhost ~]$ rpm -a crontab

    没有安装就通过yum方式安装

    [root@localhost ~]$ yum install crontabs

    crontab命令是需要crond 服务支持的,crond服务同样是独立的服务,所以启动和自启动方法如下:

    [root@localhost ~]$ service crond restart 停止 crond: [确定] 正在启动crond: [确定] #重启动crond服务 [root@localhost ~]$ chkconfig crond on #设定crond服务为开机自启动

    .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 文件。

    2. crontab 命令

    语法格式:

    [root@localhost ~]$ crontab [选项] at 命令选项及含义 选项含义-e创建、编辑crontab定时任务-l查询crontab任务-r删除当前用户所有的crontab任务,如果有多个任务,只想删除一个,可以用"crontab -e"-u 用户名修改或删除其他用户的crontab任务,只有root可用[root@localhost ~]$ crontab -e #进入crontab编辑界面,会打vim编辑你的工作 * * * * * 执行的任务命令 分 时 日 月 周 创建好的定时任务会在/etc/crontab保存 项目含义范围第一个“*”一小时当中的第几分钟0-59第二个“*”一天当中的第几小时0-23第三个“*”一个月当中的第几天1-31第四个“*”一年当中的第几月1-12第五个“*”一周当中的星期几0-7(0和7都代表星期日)

    另外,还有一些辅助的字符,大概有下面这些:

    特殊字符代表意义*代表任何时刻都接受的意思。举例来说,0 12 * * * command 日、月、周都是*,就代表着不论何月、何日的礼拜几的12:00都执行后续命令的意思。,代表分隔时段的意思。举例来说,如果要执行的工作是3:00与6:00时,就会是:0 3,6 * * * command时间还是有五列,不过第二列是 3,6 ,代表3与6都适用-代表一段时间范围内,举例来说,8点到12点之间的每小时的20分都进行一项工作:20 8-12 * * * command仔细看到第二列变成8-12.代表 8,9,10,11,12 都适用的意思*/n那个n代表数字,即是每隔n单位间隔的意思,例如每五分钟进行一次,则:/5 * * * * 命令 用与/5来搭配,也可以写成0-59/5,意思相同

    时间常用举例

    每分钟定时执行一次规则: 每1分钟执行: */1 * * * *或者* * * * * 每5分钟执行: */5 * * * * 每隔60分钟执行一次: */60 * * * *

    每小时定时执行一次规则: 每小时执行: 0 * * * *或者0 */1 * * * 每天上午7点执行:0 7 * * * 每天上午7点10分执行:10 7 * * *

    每天定时执行一次规则: 每天执行 0 0 * * *

    每周定时执行一次规则: 每周执行 0 0 * * 0

    每月定时执行一次规则: 每月执行 0 0 1 * *

    每年定时执行一次规则: 每年执行 0 0 1 1 *

    其他例子

    5 * * * * 指定每小时的第5分钟执行一次ls命令

    30 5 * * * ls 指定每天的 5:30 执行ls命令

    30 7 8 * * ls 指定每月8号的7:30分执行ls命令

    30 5 8 6 * ls 指定每年的6月8日5:30执行ls命令

    30 6 * * 0 ls 指定每星期日的6:30执行ls命令[注:0表示星期天,1表示星期1,以此类推,也可以用英文来表示,sun表示星期天,mon表示星期一等。]

    30 3 10,20 * * ls 每月10号及20号的3:30执行ls命令[注:“,”用来连接多个不连续的时段]

    25 8-11 * * * ls 每天8-11点的第25分钟执行ls命令[注:“-”用来连接连续的时段]

    */15 * * * * ls 每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]

    30 6 */10 * * ls 每个月中,每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6:30执行一次ls命令。

    例子1:让系统每隔5分钟,就向/tmp/test文件中写入一行“11”,验证一下系统定时任务是否会执行

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

    例子2:在系统在每周二的凌晨5点05分重启一次

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

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

    [root@localhost ~]$ crontab -e 30 3 1,10,15**/root/sh/autobak.sh [root@localhost ~]$ crontab -l #查看root用户的crontab任务 [root@localhost ~]$ crontab -r #删除root用户所有的定时任务,如果只想删除某一个定时任务, #可以“crontab -e”进入编辑模式手工鹏除

    crontab 的注意事项

    在书写crontab定时任务时,需要注意几个注意事项,这里我们再强调下:

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

    3. 系统的crontab 设置

    “crontab -e”是每个用户执行的命令,也就是说不同的用户身份可以执行自己的定时任务。可是有些定时任务需要系统执行,这时我们就需要编辑/etc/crontab这个配置文件了。当然,并不是说写入/etc/crontab配置文件中的定时任务执行时,不需要用户身份,而是“crontab-e”命令定义定时任务时,默认用户身份是当前登录用户。而修改/etc/crontab配置文件时,定时任务的执行着身份是可以手工指定的。这样定时任务的执行会更加灵活,修改起来也更加方便。 那我们打开这个文件看看吧:

    [root@localhost ~]$ vim /etc/crontab SHELL=/bin/bash #标示使用哪种shel1 PATH=/sbin:/bin:/usr/sbin:/usr/bin #指定PATH环境变量,crontab是使用自己的 PATH,而不是用系统默认的,所以在定时任务中出现的命令最好使用大写 MAILTO=root #如1果有报错输出,或命令结果又输出,会向root发信息 HOME=/ #标示主目录 For details see man 4 crontabs #提示大家可以去“man 4 crontabs”查看帮助 #Example of job definition: # .-----—--—------- minute (0 - 59) # | .——-—-————---- hour (o - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12)OR jan,feb,mar, apr ... # | | | | .---- day of week(O - 6)(Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri, sat # | | | | | # * * * * * user-name command to be executed #分 时 日 月 周 执行者身份 命令 #列出文件格式,并加入了注释

    在CentOS 6.x中,/etc/crontab这个文件也发生了变化,在CentOS 5.x中这个文件的内容大概是这个样子:

    #以下输出,是在CentOS5.5当中 [root@localhost ~]$ vim /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # run-parts 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly

          在CentOS5.x版本中,/etc/crontab文件会使用run-parts脚本执行/etc/cron.{daily,weekly, monthly}目录中的所有文件。这个run-parts其实是一个shell脚本,保存在/usr/bin/run-parts,它的作用就是把其后面跟随的目录中的所有可执行文件依次执行。也就是说,如果我们想让某个脚本在每天都执行一次,可以不用手工去写定时任务,而只需要给这个脚本赋予执行权限,并把它放入/etc/cron.daily/目录中。这样这个脚本就会在每天的凌晨4点02分执行了。

          可是在CentOS 6.x版本中,/etc/crontab文件中不再有相关的段落,那么是否run-ptars这种定时任务执行方法不可用了呢?我们看到/etc/crontab中有一句提示,让我们“man 4 crontabs”来查看帮助,那么我们就看看这个帮助吧!在这个帮助中,明确写明了“在旧版本的crontab配置文件中,是通过run-parts脚本来调用cron.fdaily,weekly, monthly}目录,定时执行这些目录中的脚本。在当前系统中,为了避免cron和 anacron之间产生冲突,只要 anacron已经安装,就使用anacron来执行这些目录中的脚本。具体可以查看anacron(8)的帮助。”。对于anacron的用法,我们下面来介绍。

    其实对我们用户来讲,我们并不需要知道这个定时任务到底是由哪个程序调用的。我们需要知道的事情是如何使用系统的crontab设置。这个新老版本的CentOS没有区别,配置方法都有两种:

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

    第二种方法就是修改/etc/crontab这个配置文件,自己加入自己的定时任务,不过需要注意指定脚本的执行者身份。

    例如:

    [root@localhost ~]$ vi /etc/crontab …省略部分输出… * * * * * root run-parts /root/cron/ #让系统每分钟都执行一次/root/cron/目录中的脚本,脚本执行者是root用户。 #虽然在CentOS 6x中,不是直接通过此配置文件调用/etc/cron. fdaily,weekly, monthly}这些目录, #但是run-parts脚本还是可以使用的。所以我完全可以参照CentOS 5.x的方法来写定时任务。 #使用run-parts脚本调用并执行/root/cron/目录中所有的可执行文件 [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文件,这个定时任务就可以执行了,当然要确定crond服务是运行的。这两种方法都是可以使用的,具体看个人的习惯吧!不过要想修改/etc/crontab文件,当然我要是root用户才可以,普通不能修改,只能使用用户身份的crontab命令。

    anacron

    anacron 是用来干什么的呢?我们的Linux服务器如果不是24小时开机的,那么刚好在关机的时间段之内有系统定时任务(cron)需要执行,那么这些定时任务是不会执行的。也就是说,假设我们需要在凌晨5点05分执行系统的日志备份,但是我们的 Linux 服务器不是24小时开机的,在晚上需要关机,白天上班之后才会再次开机。这个定时任务的执行时间我们的服务器刚好没有开机,那么这个任务就不会执行了。a nacron 就是用来解决这个问题的。

    anacron 会使用一天,七天,一个月作为检测周期,用来判断是否有定时任务在关机之后没有执行,如果有这样的任务,anacron 会在特定的时间重新执行这些定时任务。那么 anacron 是如何判断这些定时任务已经超过了执行时间呢?在系统的 /var/spool/anacron/ 目录中存在 cron. {fdaily, 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.{fdaily,weekly,monthly}目录中的定时任务程序只会被 anacron 调用,从而保证这些定时任务只会在每天、每周或每月被定时执行一次,而不会重复执行。这也是我们在上一个小节中介绍的CentOS6.x的变化之一。

    在CentOS 6.x中 anacron 还有一个变化,anacron 不再是单独的服务,而变成了系统命令。也就是说我们不再可以使用 “service anacron restart” 命令来管理 anacron 服务了。而是需要使用 anacron 命令来管理 anacron 工作。

    具体命令如下:

    [root@localhost ~]$ anacron[选项][工作名] 选项: -s: 开始 anacron 工作,依据 /etc/anacrontab 文件中的设定的延迟时间执行 -n: 立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间 -u: 更新/var/spool/anacron/cron.{daily, weekly,monthly}文件中的时间戳,但不执行任何工作 参数: 工作名: 是依据/etc/anacrontab文件中定义的工作名

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

    [root@localhost ~]$ vim /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_HOURS_RANGE=3-22 #anacron 的执行时问范围是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的执行过程:

    首先读取/var/spool/anacron/cron.daily中的上一次anacron执行的时间;和当前时间比较,如果两个时间的差值超过1天,就执行cron.daily工作;执行这个工作只能在03:00-22:00之间;执行工作时强制延迟时间为5分钟,再随机延迟0-45分钟时间;使用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 ~]$ vimvi /etc/anacrontab # /etc/anacrontab: configuration file for anacron #S ee 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=O #随机延迟改为О分钟,不再随机延迟 the jobs will be started during the following hours only START_HOURS_RANGE=3-5 #执行时间范国为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 #强制延迟也改为О分钟,不再强制延迟

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

    Processed: 0.009, SQL: 8