如何使用 Cron 在 Ubuntu 18.04 上自动执行任务
介绍
Cron 是一种基于时间的作业调度守护进程,可在类 Unix 操作系统(包括 Linux 发行版)中找到。 Cron 在后台运行,使用 cron
安排的操作(称为“cron 作业”)会自动执行,这使得 cron 可用于自动执行与维护相关的任务。
本指南概述了如何使用 cron 的特殊语法安排任务。它还介绍了一些快捷方式,您可以使用这些快捷方式来加快编写工作计划的过程并使它们更易于理解。
先决条件
要完成本指南,您需要访问运行 Ubuntu 18.04 的计算机。这可以是您的本地计算机、虚拟机或虚拟专用服务器。
无论您使用哪种计算机来遵循本指南,它都应该有一个配置了管理权限的非根用户。要进行设置,请遵循我们的 Ubuntu 18.04 初始服务器设置指南。
安装 Cron
几乎每个 Linux 发行版都默认安装了某种形式的 cron
。但是,如果您使用的是未安装 cron
的 Ubuntu 计算机,则可以使用 APT 安装它。
在 Ubuntu 机器上安装 cron
之前,更新计算机的本地包索引:
- sudo apt update
然后使用以下命令安装 cron
:
- sudo apt install cron
您需要确保它也设置为在后台运行:
- sudo systemctl enable cron
OutputSynchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable cron
之后,cron
将安装在您的系统上并准备好开始安排作业。
了解 Cron 的工作原理
Cron 作业在称为 crontab
的特殊文件中进行记录和管理。系统上的每个用户配置文件都可以有自己的 crontab
,他们可以在其中安排作业,这些作业存储在 /var/spool/cron/crontabs/
下。
要安排工作,请打开您的 crontab
进行编辑并添加以 cron 表达式 形式编写的任务。 cron 表达式的语法可以分为两个元素:计划和要运行的命令。
该命令实际上可以是您通常在命令行上运行的任何命令。语法的 schedule 组件分为 5 个不同的字段,按以下顺序编写:
Field | Allowed Values |
---|---|
minute | 0-59 |
hour | 0-23 |
Day of the month | 1-31 |
month | 1-12 or JAN-DEC |
Day of the week | 0-6 or 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
、6
、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
任务的时间表,可以使用 \Crontab Guru 来检查您的 cron
时间表是有效的。
管理 Crontab
一旦你确定了一个时间表并且你知道你想要运行的作业,你需要把它放在你的守护进程能够读取它的地方。
如前所述,crontab
是一个特殊文件,其中包含作业 cron
将运行的时间表。但是,这些并不打算直接编辑。相反,建议您使用 crontab
命令。这允许您编辑用户配置文件的 crontab
,而无需使用 sudo
更改您的权限。如果 crontab
中有语法错误,crontab
命令也会让您知道,而直接编辑则不会。
您可以使用以下命令编辑您的 crontab
:
- crontab -e
如果这是您第一次在此用户配置文件下运行 crontab
命令,它会提示您选择默认文本编辑器以在编辑 crontab
时使用:
Outputno crontab for sammy - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]:
输入与您选择的编辑器对应的编号。或者,您可以按 ENTER
接受默认选择 nano
。
做出选择后,您将被带到一个新的 crontab
,其中包含一些关于如何使用它的注释掉的说明:
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
当您以后运行 crontab -e
时,它会自动在此文本编辑器中调出您的 crontab
。进入编辑器后,您可以在新行中输入每个作业的日程安排。否则,您可以暂时保存并关闭 crontab(CTRL + X
,Y
,如果您选择了 nano,然后 ENTER
代码>)。
注意:在 Linux 系统上,/etc/
目录下还有一个 crontab
。这是一个系统范围的 crontab
,它有一个附加字段,每个 cron
作业都应在该字段下运行。本教程侧重于用户特定的 crontab
,但如果您想编辑系统范围的 crontab
,您可以使用以下命令来完成:
- sudo nano /etc/crontab
如果您想查看 crontab
的内容,但不想编辑它,您可以使用以下命令:
- crontab -l
您可以使用以下命令清除您的 crontab
:
警告:以下命令不会要求您确认是否要删除您的 crontab
。只有在确定要删除它时才运行它。
- crontab -r
此命令将立即删除用户的 crontab
。但是,您可以包含 -i
标志,让命令提示您确认您确实要删除用户的 crontab
:
- crontab -r -i
Outputcrontab: really delete sammy's crontab? (y/n)
出现提示时,您必须输入 y
以删除 crontab
或输入 n
以取消删除。
管理 Cron 作业输出
因为 cron
作业是在后台执行的,所以它们是否已成功运行并不总是很明显。现在您已经知道如何使用 crontab
命令以及如何安排 cron
作业,您可以开始尝试使用一些不同的方法来重定向 cron
的输出 作业来帮助您跟踪它们是否已成功执行。
如果您在服务器上安装并正确配置了 Sendmail,则可以将 cron
任务的输出发送到与您的 Linux 用户配置文件关联的电子邮件地址。您还可以通过在 crontab
顶部提供 MAILTO
设置来手动指定电子邮件地址。
例如,您可以将以下行添加到 crontab
。其中包括一个 MAILTO
语句,后跟一个示例电子邮件地址,一个指示要运行的 shell 的 SHELL
指令(本例中为 bash
),一个HOME
指令指向搜索 cron
二进制文件和单个 cron
任务的路径:
. . .
MAILTO="example@linux教程"
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
文件中使用几个速记命令来帮助简化作业调度。它们本质上是指定的等效数字时间表的快捷方式:
Shortcut | Shorthand for |
---|---|
@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 脚本结合使用时,您可以自动执行通常繁琐或复杂的任务。例如,您可以编写一个 shell 脚本来将数据备份发送到对象存储解决方案,然后使用 cron 将其自动化。