linux关于定时执行命令

1、at命令:定时执行任务

1.1 使用这个命令需要先安装at包,并且开启atd服务。

1.1.1 检测at包是否安装

[root@localhost ~]# rpm -q at
at-3.1.13-20.el7x86_64

1.1.2 如果没有安装,使用yum安装

[root@localhost ~]# yum -y install at
#省略输出信息,最终出现 Complete!,证明安装成功。

1.1.3 开启atd服务

[root@localhost ~]# service atd start
正在启动 atd: [确定]

如果想要这个服务在开机时就启动,使用如下命令:

[root@localhost ~]# chkconfig atd on

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

1.2 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 文件即可。

对于 /etc/at.allow 和 /etc/at.deny 文件的优先级,我们做一个实验来验证一下,命令如下:

[root@localhost ~]# ls -l /etc/at*
-rw-r--r--.1 root root 1 1月 30 2012 /etc/at.deny
#系统中默认只有at.deny文件
[root@localhost ~]# echo user1 >> /etc/at.deny
[root@localhost ~]# cat /etc/at.deny
user1
#把user1用户写入/etc/at.deny文件
[root@localhost ~]# su - user1
[user1@localhost ~]$ at 02:00
You do not have permission to use at.
#没有权限使用at命令,切换成user1用户,这个用户已经不能执行at命令了
[user1@localhost ~]$ exit
logout
#返回root身份
[root@localhost ~]# echo user1 >> /etc/at.allow
[root@localhost ~]# cat /etc/at.allow
user1
#建立/etc/at.allow文件,并在文件中写入user1用户
[root@localhost ~]# su - user1
[user1@localhost ~]$ at 02:00
at>
#切换成user1用户,user1用户可以执行at命令。这时user1用户既在/etc/at.deny文件中,又在/etc/at.allow文件中,但是/etc/at.allow文件的优先级更高
[user1@localhost ~]$ exit
logout
#返回root身份
[root@localhost ~]# at 02:00
at>
#root用户虽然不在/etc/at.allow文件中,但是也能执行at命令,
#root用户虽然不在/etc/at.allow文件中,但是也能执行at命令,
#说明root用户不受这两个文件的控制

这个实验说明了 /etc/at.allow 文件的优先级更高,如果 /etc/at.allow 文件存在,则 /etc/at.deny 文件失效。/etc/at.allow 文件的管理更加严格,因为只有写入这个文件的用户才能使用 at 命令,如果需要禁用 at 命令的用户较多,则可以把少数用户写入这个文件。/etc/at.deny 文件的管理较为松散,如果允许使用 at 命令的用户较多,则可以把禁用的用户写入这个文件。不过这两个文件都不能对 root 用户生效。

1.3 命令的格式

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

1.4 选项

  • -m 当 at 工作完成后,无论命令是否输出,都用 E-mail 通知执行 at 命令的用户。

  • -c 工作标识号 显示该 at 工作的实际内容。

  • -t 时间 在指定时间提交工作并执行,时间格式为 [[CC]YY]MMDDhhmm。

  • -d 删除某个工作,需要提供相应的工作标识号(ID),同 atrm 命令的作用相同。

  • -l 列出当前所有等待运行的工作,和 atq 命令具有相同的额作用。

  • -f 脚本文件 指定所要提交的脚本文件。

1.5 时间参数的格式

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 天之后的此时此刻执行。

1.6 举例:

例 1:

[coot@localhost ~]# cat /root/hello.sh
#!/bin/bash
echo "hello world!!"
#该脚本会打印"hello world!!"
[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 2013-07-25 20:54 #这是第8个at任务,会在2013年7月25日20:54执行
[root@localhost ~]# at -c 8
#查询第8个at任务的内容
...省略部分内容...
#主要定义系统的环境变量
/root/hello.sh >> /root/hello.log
#可以看到at执行的任务

例2:

root@localhost ~J# 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:关于atq命令(atq 命令用于查看当前等待运行的工作)

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

例4:atrm 命令的用法(atrm 命令后者用于删除指定的工作)

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

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

2.1 crond服务

crond 是 Linux 下用来周期地执行某种任务或等待处理某些事件的一个守护进程,和 Windows 中的计划任务有些类似。想要运用crontab命令,就要开启这个服务(一般情况下,这个服务是自启动的)。

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

2.2 crontab命令的权限

  • 当系统中有 /etc/cron.allow 文件时,只有写入此文件的用户可以使用 crontab 命令,没有写入的用户不能使用crontab 命令。同样,如果有此文件,/etc/cron.deny 文件会被忽略,因为 /etc/cron.allow文件的优先级更高。
  • 当系统中只有 /etc/cron.deny 文件时,写入此文件的用户不能使用 crontab 命令,没有写入文件的用户可以使用crontab 命令。
  • /etc/cron.allow 文件比 /etc/cron.deny 文件的优先级高,Linux 系统中默认只有/etc/cron.deny 文件。

2.3 命令的格式

[root@localhost ~]# crontab [选项] [file]

注意,这里的 file 指的是命令文件的名字,表示将 file 作为 crontab 的任务列表文件并载入 crontab,若在命令行中未指定文件名,则此命令将接受标准输入(键盘)上键入的命令,并将它们键入 crontab。

2.4 命令的选项

  • -u user :用来设定某个用户的 crontab 服务,例如 “-u demo” 表示设备 demo
    用户的 crontab 服务,此选项一般有 root 用户来运行。
  • -e :编辑某个用户的 crontab 文件内容。如果不指定用户,则表示编辑当前用户的 crontab 文件。
  • -l :显示某用户的 crontab 文件内容,如果不指定用户,则表示显示当前用户的 crontab 文件内容。
  • -r : 从 /var/spool/cron 删除某用户的 crontab 文件,如果不指定用户,则默认删除当前用户的 crontab 文件。
  • -i :在删除用户的 crontab 文件时,给确认提示。

其实 crontab 定时任务非常简单,只需执行“crontab -e”命令,然后输入想要定时执行的任务即可。不过,当我们执行“crontab -e”命令时,打开的是一个空文件,而且操作方法和 Vim 是一致的。那么,这个文件的格式才是我们真正需要学习的内容。文件格式如下:

[root@localhost !]# crontab -e
#进入 crontab 编辑界面。会打开Vim编辑你的任务
* * * * * 执行的任务

文件介绍:
这个文件中是通过 5 个“”来确定命令或任务的执行时间的,这 5 个“”的具体含义如下:
在这里插入图片描述
在时间表示中,还有一些特殊符号需要学习,如下表:
在这里插入图片描述
当“crontab -e”编辑完成之后,一旦保存退出,那么这个定时任务实际就会写入 /var/spool/cron/ 目录中,每个用户的定时任务用自己的用户名进行区分。而且 crontab 命令只要保存就会生效,只要 crond 服务是启动的。知道了这 5 个时间字段的含义,我们多举几个时间的例子来熟悉一下时间字段,如下表:
在这里插入图片描述

2.5 举例

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

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

如果换成“*”,那么就是让它每分钟执行一次。
例2:让系统在每周二的凌晨 5 点 05 分重启一次:

[root@localhost ~]# crontab -e
5.5 * * 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

例4:查看定时任务

[root@localhost ~]# crontab -l
#查看root用户的crontab任务
*/5 * * * * /bin/echo "11" >> /tmp/test
5.5 * * 2 /sbin/shutdown -r now
30.3 1,10,15 * * /root/sh/autobak.sh
[root@localhost ~]# crontab -r
#删除root用户所有的定时任务。如果只想删除某个定时任务,则可以执行“crontab -e”命令进入
#编辑模式手工删除
[root@localhost ~]# crontab -l
no crontab for root
#删除后,再查询就没有root用户的定时任务了

2.6 总结crontab定时任务的注意事项:

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

2.7 关于系统的定时任务

3、Linux anacron命令

3.1 命令的意义

系统处于关机状态时,有定时的命令无法执行,这时需要有一个命令来解决这个问题。

3.2 命令及选项

[root@localhost ~]# anacron [选项] [工作名]

选项:

  • -f 强制执行相关工作,忽略时间戳。

  • -u 更新 /var/spool/anacron/cron.{daily,weekly,monthly} 文件中的时间戳为当前日期,但不执行任何工作。

  • -s 依据 /etc/anacrontab 文件中设定的延迟时间顺序执行工作,在前一个工作未完成前,不会开始下一个工作。

  • -n 立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间。

  • -q 禁止将信息输出到标准错误,常和 -d 选项合用。

3.3 /etc/anacrontab 文件的配置

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

[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
#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那就执行
7 25 cron.weekly nice run-parts /etc/cron.weekly
#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被执行,就会执行
©monthly 45 cron.monthly nice run-parts /etc/cron.monthly
#每隔一个月开机后 45 分钟检查 /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: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分钟,不再强制廷迟

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


版权声明:本文为lzy820260594原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。