在Linux后台中有许多的默认执行的系统服务,就像我们Windows开机时就有一个exeplorer.exe默认运行,这些系统服务称为系统守护进程。
接下来介绍两个比较重要的系统守护进程atd和crond。
当我们在Linux命令行下输入命令然后按下enter键,命令会立即执行,但是我们有时候并不希望命令立即执行,或者在某个时间自动执行,这个时候我们就用到了atd服务。
atd服务就是可以在未来指定的某个时刻执行指定命令任务的系统守护进程,可
以通过at命令进行设置atd要执行的命令以及执行命令的时间
但是atd服务的一个特点就是,这个命令执行完以后,相关的文件就会自动删除。当我们需要自动分析日志文件、定期备份系统中比较重要的文件的时候,就需要重新定义一个atd服务进程,很显然会很麻烦,因此可以借助crond服务。
crond服务就是可以周期性循环执行指定任务的系统守护进程,可以通过crontab命令设置crond服务周期性执行的命令和时间。可循环时间周期设置的参数有分、时、周、月、[年]等;除了用crontab命令设置crond系统服务以外,也可以通过编辑/etc/crontab文件配置crond服务
atd的启动与at运作的方式
atd服务负责在未来某个时刻执行某个任务,at命令可以对atd进行配置,从而生成所要运行的工作,并将这个工作以文本方式写入/var/spool/at/目录内,这个工作就可以等待atd服务调用了
当然这一切的前提都是我们的林旭安装并启动了atd服务。大部分Linux发行版都默认安装和启动了该服务;如果没有安装我们可以通过yum install at -y安装atd服务。之后通过systemctl atd statue查看该服务的状态,记得要通过命令systemctl enable atd让atd服务开机自动启动
出于安全的考虑,我们并不希望所有用户都可以使用at命令,如果系统被黑客入侵,很有可能利用at服务在系统中装入特定的脚本程序,定期搜索系统重要信息,一般会指定几个信用的用户可以使用at命令
- 寻找/etc/at.allow文件存在,写在这个文件的用户才能使用at命令
- 若/etc/at.allow文件不存在,则寻找/etc/at.deny文件,写在该文件的用户不能使用at命令
- 若两个文件都不存在,那么只有root用户可以使用at命令
注意:在Redhat Linux中由于假设系统上所有的用户都是可以信任的,所以允许所有人使用at命令,/etc/at.deny文件为空,如果想要拒绝某人使用at命令,可以将该用户写入该文件,一个用户写一行!!!
at命令详解
命令格式:at [选项] [时间]
参数 | 说明 |
-m | 当任务完成之后,即使没有标准输出,也将给用户发送邮件方式告诉用户 |
-l | atq的别名,可以 列出目前系统上所有的该用户的at待执行命令 |
-d | atrm的别名,可以删除/取消一个at中的待执行命令 |
-v | 使用较明显的时间格式,列出所有单一执行的例行性工作 |
-c | 可以列出某一例行性工作的实际命令内容 |
-f | 从文件中读取作业 |
时间格式
参数 | 说明 |
HH:MM | 在今天的HH小时MM分钟执行,如果今天的这个时间已经过了,则明天执行。例如:04:00 |
HH:MM YYYY-MM-DD | 强制规定在某年某月某日某时某分执行。例如:04:00 2022-05-20 |
now[am | pm] + 2 minutes/hours/days/weeks | 从现在开始的几分钟/小时/天/周执行。例如:now + 5 minutes 04pm + 3 days |
HH:MM[am | pm] [Mounth] [Date] | 强制某年某月某日某时刻进行。例如:05pm July 30 |
在使用at命令时会进入一个at shell的环境让用户下达工作指令,最好使用绝对路径来下达指令。因为指令的下达与PATH变量和下达命令时的工作目录有关,比如我在/tmp下达了mv haha /xixi,那个文件将是/tmp/haha,因为at在运行时,会跑到当时下达at指令的工作目录,因此选择绝对路径将会更加靠谱
如何退出at shell式界面 -- ctrl + d
循环执行的例行性工作
用户想要建立循环执行例行性工作,使用的是crontab指令,同样的,出于安全性的考虑,具有与at一样的限制规则,不过黑名单的名字叫做cron.deny;白名单叫做cron.allow,都在/etc下。
当用户使用crontab建立工作进程之后,该项工作就会被记录到/var/spool/cron里面,而且所有工作将以用户进行区别,比如root用户使用了crontab,那么这条记录将会被记录到/var/spool/cron/root中。不过不建议使用vi/vim直接编辑这个文件,可能由于编辑时的语法错误导致cron无法执行;每条例行性工作执行的日志都会被记录到/var/log/cron中。
crontab命令详解
命令格式:crontab [-u user] [ -l/r/e]
选项 | 说明 |
-u | 只有root才能执行这个选项,帮某个用户新建/删除crontab |
-e | 编辑crontab的工作内容 |
-l | 查阅crontab的工作内容 |
-r | 删除所有的crontab的工作内容 |
编辑crontab,使用命令crontab -e
文件格式为:每一行为一个工作,每项工作具有六个字段
代表意义 | 分钟 | 小时 | 日期 | 月份 | 周 | 命令 |
数字范围 | 0-59 | 0-23 | 1-31 | 1-12 | 0-7 //0和7都代表周日 | 执行的命令 |
文件内的特殊字符:
特殊字符 | 含义 |
* | 代表任何时刻 |
, | 代表分隔时段 |
| 代表一段时间范围 |
/数字 | 指定时间的间隔频率 |
场景:我设定每周末备份一次用户数据,但是恰好周日停电了,这个时候要么选择周一手动备份,要么等待下周日再进行备份,不过这与我们当初的设想是相悖的,这个时候就用到一款anacron程序了。
什么是anacron
anacron并不是用来取代crontab,anacron是一个程序,主要是用来解决因为某些不可控原因导致某个crontab中的任务在规定时间执行。anacron默认每一小时被crond服务执行一次,然后anacron再去检测有没有任务没有在期限内被执行,如果有,那就执行;执行所有此类任务之后或没有此类任务,anacron就停止了。
ana是如何知道我们的系统关机的呢?
anacron会读取时间记录文件(timestamps),anacron会去分析现在的时间与时间记录文件上次所记载的上次执行anacron的时间,两者比较后如果发现有差异,那么就是在某时刻没有进行crontab,此时anacron就会开始执行未进行的crontab任务
归根结底anacron是一个程序并非一个服务,anacron每个小时被主动执行一次,因此anacron的配置文件在/etc/cron.hourly下
所以其实也仅仅是执行anacron -s的指令,那就看看anacron这个程序
anacron的语法
anacron [-sfn] [job]
anacron -u [job]
选项 | 说明 |
-s | 开始连续的执行各项工作,会一句时间记录文件的数据判断是否执行 |
-f | 强制进行,而不去判断时间记录文件的时间戳 |
-n | 立刻执行未进行的任务,而不延迟(delay)等待时间 |
job | 有/etc/anacrontab定义的各项工作名称 |
在Linux中,anacron每个小时都会给执行一次,但是为了担心anacron误判时间参数,因此/etc/cron.hourly/里面的anacron才会在档名之前加一个0(0anacron),让anacron最先执行,就是为了时间戳先更新,以避免anacron误判crontab尚未进行任何工作的意思
看一下anacron的配置文件:/etc/anacrontab的内容:
天数 工作名称定义 实际要进行的指令串 延迟时间 # 天数单位为天;延迟时间单位为分钟;工作名称定义可自定义,指令串则通常与 crontab 的设定相同!
天数:anacron 执行当下与时间戳 (/var/spool/anacron/ 内的时间纪录文件) 相差的天数,若超过此天数,就 准备开始执行,若没有超过此天数,则不予执行后续的指令。
延迟时间:若确定超过天数导致要执行排程工作了,那么请延迟执行的时间,因为担心立即启动会有其他 资源冲突的问题吧!
工作名称定义:这个没啥意义,就只是会在 /var/log/cron 里头记载该项任务的名称这样!通常与后续的目 录资源名称相同即可。
实际要进行的指令串:有没有跟 0hourly 很像啊!没错!相同的作法啊!透过 run-parts 来处理的!
根据上面的配置文件内容,我们大概知道 anacron 的执行流程应该是这样的 (以 cron.daily 为例):
1. 由 /etc/anacrontab 分析到 cron.daily 这项工作名称的天数为 1 天;
2. 由 /var/spool/anacron/cron.daily 取出最近一次执行 anacron 的时间戳;
3. 由上个步骤与目前的时间比较,若差异天数为 1 天以上 (含 1 天),就准备进行指令;
4. 若准备进行指令,根据 /etc/anacrontab 的设定,将延迟 5 分钟 + 3 小时 (看 START_HOURS_RANGE 的设定);
5. 延迟时间过后,开始执行后续指令,亦即 run-parts /etc/cron.daily 这串指令;
6. 执行完毕后, anacron 程序结束。
如此一来,放置在 /etc/cron.daily/ 内的任务就会在一天后一定会被执行的!因为 anacron 是每个小时被执行一次嘛! 所以,现在你知道为什么隔了一阵子才将 CentOS 开机,开机过后约 1 小时左右系统会有一小段时间的忙碌! 而且硬盘会跑个不停!那就是因为 anacron 正在执行过去/etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ 里头的未进行的各项工作排程
总结配置文件与目录的关系:
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/内的执行文件, 以进行固定周期需要执行的指令。
也就是说,如果你每个周日的需要执行的动作是放置于 /etc/crontab 的话,那么该动作只要过期了就过期了,并不会被抓回来重新执行。 但如果是放置在 /etc/cron.weekly/ 目录下,那么该工作就会定期,几乎一定会在一周内执行一次~如果你关机超过一周, 那么一开机后的数个小时内,该工作就会主动的被执行喔! 真的吗?对!因为 /etc/anacrontab 的定义
基本上,crontab 与 at 都是定时去执行,过了时间就过了!不会重新来一遍~那anacron 则是定期去执行,某一段周期的执行~ 因此,两者可以并行,并不会互相冲突