0. 概述

在之前我介绍过 Linux 下的 Crontab 配置的语法:Crontab使用教程,但是这是简单地介绍一下如何配置以及如何定位问题之类的,这篇文章我将着重地介绍关于 Crontab 的各种配置是什么意思,以及如何被加载的。

1. cron vs anacron

在我用的系统(Arch 系)中,运行着一个 crond,例如:

[[email protected]]# systemctl status cronie
● cronie.service - Periodic Command Scheduler
     Loaded: loaded (/usr/lib/systemd/system/cronie.service; enabled; vendor preset: disabled)
     Active: active (running) since Mon 2020-08-03 20:19:37 HKT; 1h 43min ago
   Main PID: 709 (crond)
      Tasks: 1 (limit: 13364)
     Memory: 1.9M
     CGroup: /system.slice/cronie.service
             └─709 /usr/bin/crond -n

但是,当你看 crond 的 man 文档的时候,你会发现有这么一段:

Cron also searches for /etc/anacrontab and any files in the /etc/cron.d directory, which have a different format (see crontab(5))

然而看 man 5 crontab 文档也没看出 anacron 是什么,所以直接看 man anacron 会更简单一些。其实他们之间的联系很简单:

2. crond 读取的目录

根据文档显示,crond 会读取几个位置的配置文件,分别是:

3. anacron 如何被执行

看上面 anacron 的配置文件似乎不在 crond 的读取目录中,那么 anacron 的任务又是如何被执行的呢?于是我就跟踪了一下,发现这么一条调用链路:

[[email protected]]# 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
[[email protected]]# ll /etc/cron.hourly 
总用量 24
drwxr-xr-x   2 root root  4096  3月 11 22:30 .
drwxr-xr-x 104 root root 12288  8月  3 22:23 ..
-rwxr-xr-x   1 root root   580 11月  1  2019 0anacron

然后再来看下 /etc/cron.hourly/0anacron 的任务详情:

[[email protected]]# cat /etc/cron.hourly/0anacron
# 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
... ...

这一段是这个,那么可以发现,anacrontab 将执行任务的上一次时间记录在了文件:/var/spool/anacron/cron.daily 中,执行的第一件事就是确认一下今天有没有运行,如果运行了,因为最小执行单位是天,所以就不用检查了,直接跳过。(那么问题来了,如果新增了每日任务,今天就不会执行了?)

第二段代码就是:Do not run jobs when on battery power,检测是否运行在电池工作的状态,如果是,那么也不执行。

第三段代码就一句:/usr/sbin/anacron -s,看一下文档的意思:Serializes execution of jobs. Anacron does not start a new job before the previous one finished.,那么整条链路也就串起来了。

4. Ref