如何在Linux上使用Cron
Cron 是 Linux 操作系统中一个基本而强大的工具。这些基于时间的作业调度器对于系统管理员、开发人员和技术爱好者来说都是必不可少的,可以实现日常任务的自动化。
本文旨在揭开 cron 作业的神秘面纱。它提供了一个全面的指南,解释了什么是 cron 作业,它们是如何工作的,最重要的是,如何使用它们来自动执行 Linux 系统上的重复性任务。
因此,无论您的目标是设置自动备份文件、在特定时间运行脚本,还是自动化您的个人项目,本文都将向您展示 cron 作业如何使这一切成为可能。所以,让我们开始吧!
Cron 是什么
Cron 是类 Unix 操作系统(包括 Linux 和 macOS)中基于时间的作业调度器。它使用户能够安排作业(命令或脚本)在固定的时间、日期或间隔定期运行。
它最常用于自动执行系统维护或管理任务,但它也可以用于需要定期执行计划命令的其它任何目的。
Cron 如何工作
后台的核心组件是 cron 守护进程,名为 crond。它的主要工作是检查计划任务并在指定时间到来时执行它们。
守护进程每分钟唤醒一次,以检查 crontab 文件或基于目录的配置中的任务。这自然而然地将我们带到了 Cron 的下一个关键方面——它使用的文件和目录。
Cron 文件和目录
Crontab 文件是 cron 作业调度系统的核心。“Crontab”代表“cron table”,因为这些文件包含着计划时间运行的命令列表。
crontab 文件中的每一行都代表一个单独的作业,并包含有关何时运行作业的信息,然后是要执行的命令。
从本质上讲,crontab 文件有两种类型:个人用户拥有的文件和系统范围的/etc/crontab
。以下是您应该了解的有关两者的关键细节。
但在此之前,有一些重要的事情需要澄清。属于个人用户的 cron 文件不会保存在其主目录中,而是位于/var/spool/cron
目录中。同时,系统服务和应用程序的 cron 作业文件通常放在/etc/cron.d
中。
用户 crontabs
用户 crontab 对于系统上的每个用户都是个人的。用户可以在其用户 ID 下拥有他们的 crontab 文件来计划任务。
用户 crontabs 的主要优点是它们允许单个用户管理他们的作业计划,而无需管理权限。
系统的 Crontab
与用户特定的 crontab 文件不同,/etc/crontab
是系统范围的配置文件。它遵循与用户 crontabs 略有不同的格式,包括一个用户字段,该字段指定命令应在其下运行的用户帐户。
这允许系统管理员安排作业在任何用户下运行,而无需修改该用户的 crontab,从而在不同用户帐户的任务管理中具有更大的灵活性。
通常,/etc/crontab
文件通常用于需要以管理权限运行的作业或对系统运行至关重要的作业。
另一个重要的一点是,虽然用户可以编辑他们的 crontab 条目,但系统范围的 crontab 只能由 root 用户直接编辑。
Cron 的目录
除了 crontab 文件之外,大多数 Linux 系统还包含一组目录,这些目录由 cron 扫描以查找计划作业:/etc/cron.daily
、/etc/cron.hourly
、/etc/cron.weekly
和/etc/cron.monthly
。
这些目录允许更直接地调度需要定期运行的任务,而无需在 crontab 中指定确切的时间。
放置在这些目录中的脚本和可执行文件分别每天、每小时、每周或每月运行一次。这些目录中的脚本执行的确切时间由/etc/crontab
中的配置或守护进程的配置文件(通常位于/etc/cron.d/
中)确定。
Cron 语法基础
cron 作业由 Cron 文件 (crontab) 中的一行文本定义。每行由一系列字段组成,这些字段由空格或制表符分隔,后跟要执行的命令或脚本。cron 作业的基本语法如下:
minute hour day_of_month month day_of_week command_to_execute
让我们深入研究每个部分:
minute(0-59)
此字段指定命令运行的分钟数。它可以是 0 到 59 之间的值。例如,将此设置为 0 将在一小时开始时运行该命令。
hour(0-23)
小时字段以 24 小时格式指定。它确定在一天中的哪个小时执行命令。例如,将此设置为 14 将在下午 2 点运行该命令。
day_of_month(1-31)
此字段指定命令将运行的月份的哪一天。它可以是 1 到 31 之间的任何值,具体取决于当月的天数。例如,将此值设置为 1 将在每个月的第一天运行该命令。
month(1-12)
month 字段确定命令将在哪个月份执行。它可以是 1(1 月)到 12(12 月)之间的值。例如,将此值设置为 12 将在 12 月执行该命令。
day_of_week(0-6)
此字段指定命令应在一周中的哪一天运行。它可以是 0(星期日)到 6(星期六)之间的值。例如,将此值设置为 5 将每周五运行该命令。
command_to_execute
最后,在command_to_execute字段中,您可以指定 cron 作业应执行的操作。这可以是 Cron 守护进程将在指定时间执行的任何命令或脚本文件的路径。
Cron 语法中的特殊字符
Cron 语法还支持特殊字符来指定更复杂的调度模式:
*
: 表示“每个”时间单位。例如,小时字段中的*
表示“每小时”。,
: 允许指定值列表。例如,day_of_week字段中的1,3,5
表示“星期一、星期三和星期五运行”。-
: 定值范围。例如,小时字段中的9-17
表示“从上午 9 点到下午 5 点每小时”。/
: 指定增量。例如,分钟字段中的*/10
表示“每 10 分钟”。
除此之外,cron 作业还有特殊的快捷方式字符串,可以替换时间和日期的五个字段。通过这些快捷方式,可以快速指定需要数字表示形式的相同计划。
字符串 | 意义 |
---|---|
@reboot | 在启动时运行一次指定的命令。 |
@yearl,@annually | 两者都在每年 1 月 1 日凌晨 12:00 运行指定的任务。等同于指定0 0 1 1 * 。 |
@monthly | 每月 1 日凌晨 12:00 运行一次作业。相当于0 0 1 * * 。 |
@weekly | 每周星期日凌晨 12:00 运行一次作业。相当于0 0 * * 0 。 |
@daily,@midnight | 两者都在每天凌晨 12:00 运行 cronjob。这相当于在 crontab 文件中指定 0 0 * * * 。 |
@hourly | 在每小时的顶部运行作业。相当于0 * * * * 。 |
cron 作业何时开始
cron 系统每分钟对 crontab 运行一次检查。当设定的时间(分钟、小时和月)与实际时间对齐时,它会运行任务。此外,它还会检查日期:如果月份或星期几中的特定日期与今天匹配,那么就该执行命令或脚本了。
Cron 作业和路径
当 cron 作业运行时,它会在受限环境中执行此操作,这意味着它不会自动继承用户或系统的环境变量或路径。这可能会导致 cron 作业失败的问题,因为它会由于路径未定义或不正确而无法找到必要的可执行文件或脚本。
鉴于此,您可以在 crontab 文件中显式设置 PATH 环境变量,以处理 cron 作业中的路径。这告诉 cron 守护进程在哪里查找可执行文件。例如:
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
在 crontab 文件的开头添加此行可确保下面的所有 cron 作业都将在这些目录中搜索可执行文件。
但是,考虑到并遵循最佳实践,我们建议始终指定 cron 作业中所有可执行文件和脚本的绝对路径,以避免任何歧义和潜在错误。
此外,在依赖自动执行之前,请使用 crontab 中定义的相同路径和环境设置手动运行脚本或命令,以确保它们按预期工作。
设置和管理 Cron 作业
现在让我们把理论放在一边。您已掌握有关 cron 作业如何运行及其组件的所有基本知识。是时候深入了解激动人心的部分了:创建一个 cron 作业任务。
创建用户的 Cron 作业
要创建或编辑用户的 crontab 文件,请在终端中使用以下命令:
crontab -e
这是用户创建和编辑 cron 作业的标准方式。执行时,它通过在为系统设置的默认文本编辑器(例如 Vi、Nano 或其他文本编辑器)中打开用户的 crontab 文件来编辑运行命令的用户的 cron 作业。
如果这是您第一次使用该命令,系统可能会提示您选择一个编辑器,然后再继续。
接下来,要添加 cron 作业,只需按照上述语法向 crontab 文件添加一个新行即可。例如,我们将计划位于用户主目录中的备份脚本“backup.sh”在每天凌晨 3:00 运行,方法是添加以下行:
0 3 * * * /home/linuxiac/backup.sh
许多以“#”符号为前缀的行,因此在文件开头被注释掉,作为设置 cron 作业的简洁指南。
接下来,保存并退出编辑器。请记住,Cron 服务会自动检查对 crontab 文件的更改并相应地应用它们,因此您在进行更改后无需重新启动它。
最后,值得注意的是,使用提供了一个额外的好处,即在保存和退出文件时自动检查语法。Cron 会提醒您检测到的任何错误,从而提供宝贵的保护措施,防止意外进入无效的 cron 作业。
创建系统范围的 cron 作业
由于它侧重于单个用户的 crontabs,因此它不是为某些管理任务可能需要的系统范围的 Cron 配置更改而设计的。
如果是这种情况,直接编辑 “/etc/crontab” 文件可以为您提供系统范围的 crontab 功能。与特定于用户的 crontab 不同,此文件可以包含系统范围的任务,并支持为每个任务指定用户,从而为在不同用户帐户下运行命令提供了灵活性。
例如,让我们创建一个系统范围的 cron 作业,该作业将在凌晨 2:00 从/var/log/myservice
目录中删除所有扩展名为.log
的文件。
为此,我们首先使用首选的终端编辑器打开 /etc/crontab
文件:
sudo vim /etc/crontab
然后我们进入 cron 作业,它看起来像这样:
0 2 * * * root /usr/bin/find /var/log/myservice -type f -name '*.log' -delete
这与用户 cron 作业的不同之处在于,在最初的五次字段之后包含一个额外的列。此列允许指定将在其下执行作业的用户帐户 - 在本例中为 root。
但是,直接编辑 /etc/crontab
文件有两个主要缺点。首先,这种方法不提供语法检查,增加了出错的风险。
第二个是因为 /etc/crontab
影响了整个系统;不正确的条目可能会产生广泛的影响,可能会影响系统的稳定性或安全性。因此,请谨慎使用。
列出用户 Cron 作业
为确保您的 cron 作业已正确调度,您可以使用以下方法显示用户的 crontab 文件内容:
crontab -l
此命令列出为您的用户计划的所有 cron 作业,允许您验证或查看要运行的任务集。
列出系统范围的 Cron 作业
正如我们已经知道的,系统范围的 cron 作业存储在不同的位置,并且不会在用户的 crontab 中列出。要列出系统范围的 cron 作业,您需要查看 /etc/crontab
文件和目录 /etc/cron.d/
、/etc/cron.daily/
、/etc/cron.hourly/
、/etc/cron.weekly/
和 /etc/cron.monthly/
。
您可以使用命令或任何文本编辑器查看这些文件。
sudo cat /etc/crontab
列出其他用户的 Cron 作业
如果您具有超级用户 (root) 权限,则可以使用 crontab 命令为系统上的任何用户列出 cron 作业,该命令带有“-u”选项,后跟用户名和“-l”选项。例如,要列出名为“bobby”的用户的 cron 作业,您可以运行:
sudo crontab -u bobby -l
此命令对于跨多个用户帐户管理 cron 作业的系统管理员非常方便。
编辑 Cron 作业
要编辑 cron 作业(类似于创建),请使用以下命令在默认编辑器中打开当前用户的 crontab 文件:
crontab -e
打开 crontab 文件时,导航到包含您希望编辑的 cron 作业的行,并根据需要修改计划或命令,然后保存并退出该文件。
如果您需要编辑另一个用户的 crontab 文件(假设您具有必要的权限),例如,用户“bobby”,请使用:
删除 Cron 作业
根据您的目标,您有几种方法可以删除 cron 作业。要仅删除特定作业,请使用命令打开 crontab 文件。
crontab -e
从那里,导航到表示要删除的作业的行。通过完全删除该行来删除该作业。同时,请注意保持所有其他行相同。之后,保存您的更改并退出编辑器。
但是,如果您希望删除用户的所有计划 cron 作业,则可以删除用户的 crontab 文件。此操作将清除所有计划任务,因此应谨慎执行。
打开终端并输入如下所示的命令:
crontab -r
这将在不显示确认提示的情况下删除当前用户的 crontab 文件,因此请确保在执行它之前要继续。
如果您希望在删除之前收到确认提示,请使用命令crontab -i -r
。这将在删除 crontab 文件之前要求确认。
总结上面讨论的有关 crontab 命令的主要选项的关键点,下表简要概述了它们。
命令 | 描述 |
---|---|
crontab -e | 编辑 crontab 文件或创建一个(如果尚不存在)。 |
crontab -l | 显示 crontab 文件的内容。 |
crontab -r | 删除整个 crontab 文件。 |
crontab -u <user_name> | 当与其他选项配对时,此功能可以修改或查看用户的 crontab 文件,这是专为具有管理员权限的用户保留的功能。 |