Linux学习:计划任务(crontab) (15章)

1 计划任务

   1.1 Linux 工作调度的种类: at, cron

  • atat 是个可以处理仅执行一次就结束调度的指令,不过要执行 at 时, 必须要有 atd 这个[服务 (第十七章)] 的支持才行。

  • crontabcrontab 这个指令所设置的工作将会循环的一直进行下去! 可循环的时间为分钟、小时、每周、每月或每年等。crontab 除了可以使用指令执行外,亦可编辑 /etc/crontab 来支持。 至于让 crontab 可以生效的服务则是 crond 这个服务

2 仅执行一次的计划任务(at命令)

 2.1 atd 的启动与 at 运行的方式

[root@localhost ~]# systemctl restart atd    # 重新启动 atd 这个服务
[root@localhost ~]# systemctl enable atd     # 让这个服务开机就自动启动
[root@localhost ~]# systemctl status atd     # 查阅一下 atd 目前的状态
● atd.service - Job spooling tools
   Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset:  # 是否开机启动                                                                             enabled)
   Active: active (running) since 六 2023-07-01 16:10:50 CST; 36s ago            # 是否正在运行中
 Main PID: 3246 (atd)
   CGroup: /system.slice/atd.service
           └─3246 /usr/sbin/atd -f

7月 01 16:10:50 localhost.localdomain systemd[1]: Stopped Job spooling tools.
7月 01 16:10:50 localhost.localdomain systemd[1]: Started Job spooling tools.
  • at 的运行方式

使用 at 这个指令来产生所要运行的工作,并将这个工作以文本文件的方式写入 /var/spool/at/ 目录内,该工作便能等待 atd 这个服务的取用与执行了;

为了安全起见,可以利用 /etc/at.allow /etc/at.deny 这两个文件来进行 at 的使用限制;

加上这两个文件后, at 的工作情况其实是这样的:

  • 先找寻 /etc/at.allow 这个文件,写在这个文件中的使用者才能使用 at ,没有在这个文件中的使用者则不能使用 at (即使没有写在 at.deny 当中);

  • 如果 /etc/at.allow 不存在,就寻找 /etc/at.deny 这个文件,若写在这个 at.deny 的使用者则不能使用 at ,而没有在这个 at.deny 文件中的使用者,就可以使用 at ;

  • 如果两个文件都不存在,那么只有 root 可以使用 at 这个指令。

2.2 实际运行单一计划任务

at命令的基本语法与使用范例

[root@localhost ~]# at [-mldv] TIME
[root@localhost ~]# at -c 工作号码
选项与参数:
-m  :当 at 的工作完成后,即使没有输出讯息,亦以 email 通知使用者该工作已完成。
-l  :at -l 相当于 atq,列出目前系统上面的所有该使用者的 at 调度;
-d  :at -d 相当于 atrm ,可以取消一个在 at 调度中的工作;
-v  :可以使用较明显的时间格式列出 at 调度中的工作列表;
-c  :可以列出后面接的该项工作的实际指令内容。

TIME:时间格式,这里可以定义出“什么时候要进行 at 这项工作”的时间,格式有:
  HH:MM                ex> 04:00
    在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此工作。
  HH:MM YYYY-MM-DD        ex> 04:00 2015-07-30
    强制规定在某年某月的某一天的特殊时刻进行该工作!
  HH:MM[am|pm] [Month] [Date]    ex> 04pm July 30
    也是一样,强制在某年某月某日的某时刻进行!
  HH:MM[am|pm] + number [minutes|hours|days|weeks]
    ex> now + 5 minutes    ex> 04pm + 3 days
    就是说,在某个时间点“再加几个时间后”才进行。
//范例一:再过五分钟后,将 /root/.bashrc 寄给 root 自己
[root@localhost ~]# at now+5minutes
at> /bin/mail -s "testing at job" root < /root/.bashrc
at> <EOT>         #这里输入 [ctrl] + d 就会出现 <EOF> 的字样!代表结束!
job 1 at Sun Jul  2 09:56:00 2023
# 上面这行信息在说明,第 1 个 at 工作将在 2023/07/02 的 09:56 进行!
# 而执行 at 会进入所谓的 at shell 环境,让你下达多重指令等待运行!
//范例二:将上述的第 1 项工作内容列出来查阅
[root@localhost ~]# at -c 1
#!/bin/sh
# atrun uid=0 gid=0
# mail mcb 0
umask 22
....(中间省略许多的环境变量项目)....
cd /root || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER4d26473d'
/bin/mail -s "testing at job" root < /root/.bashrc     # 这一行最重要!
marcinDELIMITER4d26473d
# 你可以看到指令执行的目录 (/root),还有多个环境变量与实际的指令内容!
//范例三:由于机房预计于 2023/07/02 停电,我想要在  2023/07/02 23:10 关机?
[root@localhost ~]# at 23:10 2023-07-02
at> /bin/aync
at> /bin/sync
at> /sbin/shutdown -h now
at> <EOT>
job 2 at Sun Jul  2 23:10:00 2023
# at 还可以在一个工作内输入多个指令;

注意:

  • 使用 at 时会进入一个 at shell 的环境来让使用者下达工作指令,此时,建议你最好使用绝对路径来下达你的指令,比较不会有问题;
  • at 的执行与终端机环境无关,而所有 standard output/standard error output 都会传送到执行者的 mailbox 中!所以在终端机看不到任何信息;若想在终端显示出信息,可以采用重定向的方法;
#范例四:两分钟后在终端tty2中显示出hello;
[root@localhost ~]# at now+2minutes
at> echo "hello" > /dev/tty2
at> <EOT>
job 3 at Sun Jul  2 10:14:00 2023
#两分钟后的运行结果
[mcb@localhost ~]$ hello

at的任务管理

利用 atq atrm可以将输入错误的指令移除;

[root@localhost ~]# atq
[root@localhost ~]# atrm (jobnumber)
#范例一:查询目前主机上面有多少的 at 工作调度?
[root@localhost ~]# atq
2       Sun Jul  2 23:10:00 2023 a root
# 上面说的是:【在 2023/0702 的 23:10 有一项工作,该项工作指令执行者者为root】
# 而且,该项工作的工作号码 (jobnumber) 为 3 
#范例二:将上述的第 3 个工作移除
[root@localhost ~]# atrm 2
[root@localhost ~]# atq
[root@localhost ~]#
# 没有任何信息,表示该工作被移除了

batch 系统有空时才执行后台任务

  • 在 CPU 的工作负载小于 0.8 的时候,才进行你所下达的工作任务;
  • batch 可以拿来作为判断是否要立刻执行背景程序的依据;
范例一:请执行 pi 的计算,然后在系统闲置时,执行 updatdb 的任务
[root@study ~]# echo "scale=100000; 4*a(1)" &#124; bc -lq &
[root@study ~]# echo "scale=100000; 4*a(1)" &#124; bc -lq &
[root@study ~]# echo "scale=100000; 4*a(1)" &#124; bc -lq &
[root@study ~]# echo "scale=100000; 4*a(1)" &#124; bc -lq &
# 然后等待个大约数十秒的时间,之后再来确认一下工作负载的情况!
[root@study ~]# uptime
 19:56:45 up 2 days, 19:54,  2 users,  load average: 3.93, 2.23, 0.96

[root@study ~]# batch
at> /usr/bin/updatedb
at> <EOT>
job 4 at Thu Jul 30 19:57:00 2015

[root@study ~]# date;atq
Thu Jul 30 19:57:47 CST 2015
4       Thu Jul 30 19:57:00 2015 b root
# 可以看得到,明明时间已经超过了,却没有实际执行 at 的任务!

[root@study ~]# jobs
[1]   Running                 echo "scale=100000; 4*a(1)" &#124; bc -lq &
[2]   Running                 echo "scale=100000; 4*a(1)" &#124; bc -lq &
[3]-  Running                 echo "scale=100000; 4*a(1)" &#124; bc -lq &
[4]+  Running                 echo "scale=100000; 4*a(1)" &#124; bc -lq &
[root@study ~]# kill -9 %1 %2 %3 %4
# 这时先用 jobs 找出背景工作,再使用 kill 删除掉四个背景工作后,慢慢等待工作负载的下降

[root@study ~]# uptime; atq
 20:01:33 up 2 days, 19:59,  2 users,  load average: 0.89, 2.29, 1.40
4       Thu Jul 30 19:57:00 2015 b root
[root@study ~]# uptime; atq
 20:02:52 up 2 days, 20:01,  2 users,  load average: 0.23, 1.75, 1.28
# 在 19:59 时,由于 loading 还是高于 0.8,因此 atq 可以看得到 at job 还是持续再等待当中喔!
# 但是到了 20:01 时, loading 降低到 0.8 以下了,所以 atq 就执行完毕啰!

使用 uptime 可以观察到 1, 5, 15 分钟的“平均工作负载”量,因为是平均值,所以当我们如上表删除掉四个工作后,工作负载不会立即降低, 需要一小段时间让这个 1 分钟平均值慢慢回复到接近 0 !当小于 0.8 之后的“整分钟时间”时,atd 就会将 batch 的工作执行了;

3 crontab 循环执行的计划任务

3.1 用户的设置

为了安全性的问题, 与 at 同样的,可以限制使用 crontab 的使用者帐号:

  • /etc/cron.allow: 将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;
  • /etc/cron.deny: 将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab

crontab 命令的基本语法

[root@localhost ~]#  crontab [-u username] [-l&#124;-e&#124;-r]
选项与参数:
-u  :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作调度;
-e  :编辑 crontab 的工作内容
-l  :查阅 crontab 的工作内容
-r  :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑。

#范例一:用 mcb 的身份在每天的 12:00 发信给自己
[mcb@localhost ~]$ crontab -e
# 此时会进入 vi 的编辑画面让您编辑工作!注意到,每项工作都是一行。
0   12  *  *  * mail -s "at 12:00" mcb < /home/mcb/.bashrc
#分 时 日 月 周 &#124;<==============指令串========================>&#124;

#范例二:假若你的女朋友生日是 5 月 2 日,你想要在 5 月 1 日的 23:59 发一封信给他,这封信的内容#已经写在 /home/mcb/lover.txt 内了,该如何进行?答:直接下达 crontab -e 之后,编辑成为:
crontab -e    #进入vi编辑器,然后再vi编辑器中输入以下命令,并保存退出
59 23 1 5 * mail wm < /home/mcb/lover.txt
[root@localhost ~]# crontab -l
59 23 11 9 * mail wm < /home/mcb/lover.txt    #此时,可以查询到该任务
# 注意,若仅想要移除一项工作而已的话,必须要用 crontab -e 去编辑
# 如果想要全部的工作都移除,才使用 crontab -r 喔!
[root@localhost ~]# crontab -r
[root@localhost ~]# crontab -l
no crontab for root

重定向符号【<】为标准输入:表示从后面所接文件中输入信息,而不是通过键盘来进行输入; 

特殊字符

代表意义

*(星号)代表任何时刻都接受的意思!举例来说,范例一内那个日、月、周都是 * , 就代表着“不论何月、何日的礼拜几的 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 * * * * command ;用 * 与 /5 来搭配,也可以写成 0-59/5 ,相同意思!

无法使用crontab命令的解决方法https://blog.csdn.net/wwj256/article/details/117264059

3.2 系统的配置文件: /etc/crontab, /etc/cron.d/*

  • 执行系统的例行性任务时,只需编辑/etc/crontab即可,无需用crontab -e来管理计划任务;
  • /etc/crontab 是一个“纯文本文件”!可以用 root 的身份编辑这个文件
  • cron 这个服务的最低检测限制是“分钟”,所以【 cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容】,因此,只要你编辑完 /etc/crontab 这个文件,并且将他储存之后,那么 cron 的设置就自动的会来执行
  • 改完 /etc/crontab 之后,可能并不会马上执行,此时需重新启动 crond 这个服务,【systemctl restart crond
#查看文件/etc/crontab中的内容
[root@localhost ~]# cat /etc/crontab
SHELL=/bin/bash        #使用哪一种shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin    #执行文件查找路径
MAILTO=root                #若有额外stdout,用email将数据送给谁
# For details see 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

3.2.1 crond 服务读取配置文件的位置

一般来说,crond 默认有三个地方会有执行脚本配置文件,他们分别是

  • /etc/crontab
  • /etc/cron.d/*
  • /var/spool/cron/*

其中:/etc/crontab/etc/cron.d/*与系统的运行有关

[root@localhost ~]# ll /etc/cron.d
总用量 12
-rw-r--r--. 1 root root 128 8月   9 2019 0hourly
-rw-r--r--. 1 root root 108 9月  30 2020 raid-check
-rw-------. 1 root root 235 4月   1 2020 sysstat
# 除了 /etc/crontab 之外,crond 的配置文件还不少!上面就有三个设置!
# 查看 0hourly 这个配置文件的内容!
[root@localhost ~]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
#内容跟 /etc/crontab 几乎一模一样!但实际上是有设置值!就是最后一行
#每个整点的一分会执行“ run-parts /etc/cron.hourly ”这个指令
#run-parts 脚本会在大约 5 分钟内随机选一个时间来执行 /etc/cron.hourly 目录内的所有可执行文件

4 anacron:可唤醒停机期间的工作任务

4.1 什么是 anacron 

  • anacron 存在的目的就在于处理非 24 小时一直启动的 Linux 系统的 crontab 的执行! 以及因为某些原因导致的超过时间而没有被执行的调度工作;
  • anacron 也是每个小时被 crond 执行一次,然后 anacron 再去检测相关的调度任务有没有被执行,如果有超过期限的工作在, 就执行该调度任务,执行完毕或无须执行任何调度时,anacron 就停止了。 
  • anacron 默认会以一天、七天、一个月为期去侦测系统未进行的 crontab 任务,因此对于某些特殊的使用环境非常有帮助 

4.2 anacron 与 /etc/anacrontab

[root@localhost ~]# cat /etc/cron.hourly/0anacron
#!/bin/sh
# Check whether 0anacron was run today already
if test -r /var/spool/anacron/cron.daily; then
    day=`cat /var/spool/anacron/cron.daily`
fi
if [ `date +%Y%m%d` = "$day" ]; then
    exit 0;
fi
# 上面的语法在检验前一次执行 anacron 时的时间戳记!
# Do not run jobs when on battery power
if test -x /usr/bin/on_ac_power; then
    /usr/bin/on_ac_power >/dev/null 2>&1
    if test $? -eq 1; then
    exit 0
    fi
fi
/usr/sbin/anacron -s
# 所以其实也仅是执行 anacron -s 的指令!因此我们得来谈谈这支程序!

anacron语法详解:

[root@localhost ~]# anacron [-sfn] [job]..
[root@localhost ~]# anacron -u [job]..
#选项与参数:
-s  :开始一连续的执行各项工作 (job),会依据时间记录文件的数据判断是否进行;
-f  :强制进行,而不去判断时间记录文件的时间戳记;
-n  :立刻进行未进行的任务,而不延迟 (delay) 等待时间;
-u  :仅更新时间记录文件的时间戳记,不进行任何工作。
job :由 /etc/anacrontab 定义的各项工作名称。
[root@localhost ~]# 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    # 延迟多少个小时内应该要执行的任务时间
#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
# 天数单位为天;延迟时间单位为分钟;工作名称定义可自订,指令串则通常与 crontab 的设置相同!

最后,我们来总结一下本章谈到的许多配置文件与目录的关系吧!这样我们才能了解 crondanacron 的关系:

  1. crond 会主动去读取 /etc/crontab, /var/spool/cron/, /etc/cron.d/ 等配置文件,并依据“分、时、日、月、周”的时间设置去各项工作调度;
  2. 根据 /etc/cron.d/0hourly 的设置,主动去 /etc/cron.hourly/ 目录下,执行所有在该目录下的可执行文件;
  3. 因为 /etc/cron.hourly/0anacron 这个脚本文件的缘故,主动的每小时执行 anacron ,并调用 /etc/anacrontab 的配置文件;
  4. 根据 /etc/anacrontab 的设置,依据每天、每周、每月去分析 /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ 内的可执行文件,以进行固定周期需要执行的指令。

基本上,crontab 与 at 都是“定时”去执行,过了时间就过了!不会重新来一遍~那 anacron 则是“定期”去执行,某一段周期的执行~ 因此,两者可以并行,并不会互相冲突

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值