如何在Ubuntu18.04上使用Cron自动执行任务
介绍
Cron 是一个基于时间的作业调度守护进程,可在类 Unix 操作系统(包括 Linux 发行版)中找到。 Cron 在后台运行,使用 cron
安排的操作(称为“cron 作业”)会自动执行,这使得 cron 对于自动化维护相关任务非常有用。
本指南概述了如何使用 cron 的特殊语法安排任务。 它还介绍了一些快捷方式,您可以使用它们来加快编写工作计划的过程并使它们更易于理解。
先决条件
要完成本指南,您需要访问运行 Ubuntu 18.04 的计算机。 这可能是您的本地计算机、虚拟机或虚拟专用服务器。
无论您使用哪种计算机来遵循本指南,都应该配置一个具有管理权限的非 root 用户。 要进行此设置,请按照我们的 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 表达式的语法可以分解为两个元素:计划和要运行的命令。
该命令几乎可以是您通常在命令行上运行的任何命令。 语法的调度组件分为 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
命令,它将提示您选择默认文本编辑器以在编辑 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
作业都应在该用户配置文件下运行。 本教程侧重于用户特定的 crontabs
,但如果您想编辑系统范围的 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/n)
出现提示时,必须输入 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 脚本结合使用时,您可以自动执行通常乏味或复杂的任务。 例如,您可以 编写一个 shell 脚本来将数据备份发送到对象存储解决方案,然后使用 cron 将其自动化。