本教程的先前版本由 Shaun Lewis 编写。
介绍
Cron 是一个基于时间的作业调度守护进程,可在类 Unix 操作系统(包括 Linux 发行版)中找到。 Cron 在后台运行,使用 cron 安排的任务(称为“cron 作业”)会自动执行,这使得 cron 对于自动化维护相关任务非常有用。
本指南概述了如何使用 cron 的特殊语法安排任务。 它还介绍了一些可用于使工作计划更易于编写和理解的快捷方式。
先决条件
要完成本指南,您需要访问运行 CentOS 8 的计算机。 这可能是您的本地计算机、虚拟机或虚拟专用服务器。
无论您使用哪种计算机来遵循本指南,都应该配置一个具有管理权限的非 root 用户。 要进行此设置,请按照我们的 CentOS 8 初始服务器设置指南进行操作。
安装 Cron
几乎每个 Linux 发行版都默认安装了某种形式的 cron。 但是,如果您使用的是未安装 cron 的 CentOS 机器,您可以使用 dnf
安装它。
在 CentOS 机器上安装 cron 之前,更新计算机的本地包索引:
sudo dnf update
然后使用以下命令安装 cron 守护程序:
sudo dnf install crontabs
此命令将提示您确认是否要安装 crontabs
软件包及其依赖项。 按 y
然后按 ENTER
这样做。
这将在您的系统上安装 cron,但您需要手动启动守护程序。 您还需要确保它设置为在服务器启动时运行。 您可以使用 systemctl
命令执行这两个操作。
要启动 cron 守护程序,请运行以下命令:
sudo systemctl start crond.service
要将 cron 设置为在服务器启动时运行,请键入:
sudo systemctl enable crond.service
之后,cron 将安装在您的系统上,并准备好开始安排作业。
了解 Cron 的工作原理
Cron 作业在称为 crontab
的特殊文件中记录和管理。 系统上的每个用户配置文件都可以有自己的 crontab,他们可以在其中安排作业,这些作业存储在 /var/spool/cron/
下。
要安排作业,您只需打开 crontab 进行编辑并添加以 cron 表达式 形式编写的任务。 cron 表达式的语法可以分解为两个元素:计划和要运行的命令。
该命令几乎可以是您通常在命令行上运行的任何命令。 语法的调度组件分为 5 个不同的字段,按以下顺序编写:
场地 | 允许值 |
---|---|
分钟 | 0-59
|
小时 | 0-23
|
一个月中的哪一天 | 1-31
|
月 | 1-12 或 JAN-DEC
|
一周中的天 | 0-6 或 SUN-SAT
|
一起,在 crontab 中安排的任务的结构如下:
minute hour day_of_month month day_of_week command_to_run
这是 cron 表达式的功能示例。 此表达式每周二下午 5:30 运行命令 curl http://www.google.com
:
30 17 * * 2 curl http://www.google.com
您还可以在 cron 表达式的调度组件中包含一些特殊字符,以使调度更容易:
*
:在 cron 表达式中,星号是表示“全部”的通配符变量。 因此,使用* * * * * ...
计划的任务将在每个月的每一天的每一小时的每一分钟运行。,
:逗号将调度值分解成一个列表。 如果你想让一个任务在每小时的开始和中间运行,而不是写出两个单独的任务(例如,0 * * * * ...
和30 * * * * ...
),你可以用一个来实现相同的功能(0,30 * * * * ...
)。-
:连字符表示计划字段中的一系列值。 而不是为您想要在每小时的前 30 分钟运行的命令设置 30 个单独的计划任务(如0 * * * * ...
、1 * * * * ...
、2 * * * * ...
等) ,您可以将其安排为0-29 * * * * ...
。/
:可以使用带星号的正斜杠来表示步长值。 例如,不是写出八个独立的 cron 任务来每三个小时运行一个命令(如0 0 * * * ...
、0 3 * * * ...
、0 6 * * * ...
等),您可以安排它像这样运行:0 */3 * * * ...
。
注:不能任意表示步长值; 您只能使用在相关字段允许的范围内均分的整数。 例如,在“小时”字段中,您只能在正斜杠后面加上 1
、2
、3
、4
、[X126X ]、8
或 12
。
下面是更多关于如何使用 cron 调度组件的示例:
* * * * *
- 每分钟运行一次命令。12 * * * *
- 每小时后 12 分钟运行命令。0,15,30,45 * * * *
- 每 15 分钟运行一次命令。*/15 * * * *
- 每 15 分钟运行一次命令。0 4 * * *
- 每天凌晨 4:00 运行命令。0 4 * * 2-4
- 在每周二、周三和周四凌晨 4:00 运行命令。20,40 */8 * 7-12 *
- 在一年中最后 6 个月的每一天的第 8 小时的第 20 和第 40 分钟运行命令。
如果您发现任何这些令人困惑的地方,或者如果您想帮助为自己的 cron 任务编写计划,Cronitor 提供了一个方便的 cron 计划表达式编辑器,名为 “Crontab Guru”,您可以用于检查您的 cron 计划是否有效。
管理 Crontab
一旦你确定了一个时间表并且你知道你想要运行的工作,你需要把它放在你的守护进程能够读取它的地方。
如前所述,crontab 是一个特殊文件,其中包含 cron 将运行的作业计划。 但是,这些不打算直接编辑。 相反,建议您使用 crontab
命令。 这允许您编辑您的用户配置文件的 crontab,而无需使用 sudo
更改您的权限。 crontab
命令还会让您知道 crontab 中是否有语法错误,而直接编辑则不会。
您可以使用以下命令编辑 crontab:
crontab -e
这将在您的用户配置文件的默认文本编辑器中打开您的 crontab。
注意:在新的 CentOS 8 服务器上,crontab -e
命令将默认使用 vi
打开用户的 crontab。 vi
是一个非常强大和灵活的文本编辑器,但对于缺乏经验的用户来说,它可能会有些迟钝。
如果您想使用更平易近人的文本编辑器作为默认的 crontab 编辑器,您可以像这样安装和配置 nano
。
为此,请使用 dnf
安装 nano
:
sudo dnf install nano
出现提示时,按 y
,然后按 ENTER
确认您要安装 nano
。
要将 nano
设置为用户配置文件的默认可视化编辑器,请打开 .bash_profile
文件进行编辑。 现在您已经安装了它,您可以使用 nano
来安装它:
nano ~/.bash_profile
在文件的底部,添加以下行:
~/.bash_profile
. . . export VISUAL="nano"
这会将 VISUAL
环境变量设置为 nano
。 VISUAL
是一个 Unix 环境变量,许多程序(包括 crontab)调用它来编辑文件。 添加此行后,按 CTRL + X
、Y
,然后按 ENTER
保存并关闭文件。
然后重新加载 .bash_profile
以便 shell 获取新的更改:
. ~/.bash_profile
进入编辑器后,您可以在新行中输入您的日程安排。 否则,您现在可以保存并关闭 crontab。 如果您使用 vi
(默认的 CentOS 8 文本编辑器)打开 crontab,您可以按 ESC
以确保您处于 vi
的命令模式,然后键入 :x
并按 ENTER
。
请注意,在 Linux 系统上,/etc/
目录下存储了另一个 crontab。 这是一个系统范围的 crontab,它有一个附加字段,每个 cron 作业应该在其下运行用户配置文件。 本教程侧重于用户特定的 crontab,但如果您想编辑系统范围的 crontab,可以使用以下命令进行:
sudo nano /etc/crontab
如果您想查看 crontab 的内容,但不想编辑它,您可以使用以下命令:
crontab -l
您可以使用以下命令擦除 crontab:
Warning:以下命令不会要求您确认是否要擦除 crontab。 只有在确定要删除它时才运行它。
crontab -r
此命令将立即删除用户的 crontab。 但是,您可以包含 -i
标志,让命令提示您确认您确实要删除用户的 crontab:
crontab -r -i
Outputcrontab: really delete sammy's crontab?
出现提示时,您必须输入 y
删除 crontab 或输入 n
取消删除。
管理 Cron 作业输出
因为 cron 作业是在后台执行的,所以它们运行成功并不总是很明显。 现在您知道如何使用 crontab
命令以及如何安排 cron 作业,您可以开始尝试一些不同的方法来重定向 cron 作业的输出,以帮助您跟踪它们是否已成功执行。
如果您在服务器上安装并正确配置了 邮件传输代理 (例如 Sendmail),则可以将 cron 任务的输出发送到与您的 Linux 用户配置文件关联的电子邮件地址. 您还可以通过在 crontab 顶部提供 MAILTO
设置来手动指定电子邮件地址。
例如,您可以将以下行添加到 crontab。 其中包括 MAILTO
语句后跟示例电子邮件地址、指示要运行的 shell 的 SHELL
指令(在此示例中为 bash
)、HOME
指向搜索 cron 二进制文件和单个 cron 任务的路径的指令:
. . . MAILTO="example@digitalocean.com" SHELL=/bin/bash HOME=/ * * * * * echo ‘Run this command every minute’
此特定作业将返回“每分钟运行此命令”,并且该输出将每分钟通过电子邮件发送到 MAILTO
指令后指定的电子邮件地址。
您还可以将 cron 任务的输出重定向到日志文件或空位置,以防止收到带有输出的电子邮件。
要将预定命令的输出附加到日志文件中,请将 >>
添加到命令末尾,后跟您选择的日志文件的名称和位置,如下所示:
* * * * * echo ‘Run this command every minute’ >> /directory/path/file.log
假设您想使用 cron 来运行脚本,但要让它在后台运行。 为此,您可以将脚本的输出重定向到空位置,例如 /dev/null
会立即删除写入其中的所有数据。 例如,以下 cron 作业执行 PHP 脚本并在后台运行它:
* * * * * /usr/bin/php /var/www/domain.com/backup.php > /dev/null 2>&1
此 cron 作业还将 标准错误 — 由 2
表示 — 重定向到标准输出 (>&1
)。 因为标准输出已经被重定向到 /dev/null
,这实际上允许脚本静默运行。 即使 crontab 包含 MAILTO
语句,命令的输出也不会发送到指定的电子邮件地址。
限制访问
您可以通过cron.allow
和cron.deny
文件来管理允许哪些用户使用crontab
命令,这两个文件都存储在/etc/
目录下。 如果 cron.deny
文件存在,则其中列出的任何用户都将被禁止编辑其 crontab。 如果 cron.allow
存在,则只有其中列出的用户才能编辑他们的 crontab。 如果两个文件都存在并且每个文件中都列出了相同的用户,则 cron.allow
文件将覆盖 cron.deny
并且用户将能够编辑他们的 crontab。
例如,要拒绝所有用户访问,然后授予用户 ishmael 访问权限,您可以使用以下命令序列:
sudo echo ALL >>/etc/cron.deny sudo echo ishmael >>/etc/cron.allow
首先,我们通过将 ALL
附加到 cron.deny
文件来锁定所有用户。 然后,通过将用户名附加到 cron.allow
文件,我们授予 ishmael 用户配置文件访问权限以执行 cron 作业。
请注意,如果用户具有 sudo
权限,他们可以使用以下命令编辑另一个用户的 crontab:
sudo crontab -u user -e
但是,如果 cron.deny
存在且 user 列在其中,而它们未列在 cron.allow
中,则运行上一条命令后将收到以下错误:
OutputThe user user cannot use this program (crontab)
默认情况下,大多数 cron 守护程序将假定所有用户都可以访问 cron,除非 cron.allow
或 cron.deny
存在。
特殊语法
您还可以在 crontab 文件中使用几个速记命令来帮助简化作业调度。 它们本质上是指定的等效数字计划的快捷方式:
捷径 | 的简写 |
---|---|
@hourly
|
0 * * * *
|
@daily
|
0 0 * * *
|
@weekly
|
0 0 * * 0
|
@monthly
|
0 0 1 * *
|
@yearly
|
0 0 1 1 *
|
注意:不是所有的 cron 守护进程都可以解析这个语法(尤其是旧版本),所以在你依赖它之前仔细检查它是否有效。
此外, @reboot
简写将在服务器启动时运行它后面的任何命令:
@reboot echo "System start up"
尽可能使用这些快捷方式有助于更轻松地解释 crontab 中的任务计划。
结论
Cron 是一个灵活而强大的实用程序,可以减轻与系统管理相关的许多任务的负担。 与 shell 脚本结合使用时,您可以自动执行通常乏味或复杂的任务。