如何在Linux上使用Cron:技巧、窍门和示例

in #cn4 months ago

Cron作业是Linux操作系统中基础但功能强大的工具。这些基于时间的任务调度器对于系统管理员、开发人员和技术爱好者来说都是不可或缺的,它们能够自动化日常任务。

本文旨在揭开Cron作业的神秘面纱。它提供了一份全面的指南,解释了Cron作业是什么,它们如何工作,以及最重要的是,如何使用它们来自动化Linux系统上的重复性任务。

因此,无论你的目标是设置自动备份文件、在特定时间运行脚本,还是自动化你的个人项目,本文将向你展示Cron作业如何使一切成为可能。让我们开始吧!

什么是Cron?

Cron是类Unix操作系统中基于时间的工作调度器,包括Linux和macOS。它使用户能够定期在固定的时间、日期或间隔运行作业(命令或脚本)。

它最常用于自动化系统维护或管理任务,但也可用于任何需要定期、预定执行命令的目的。

Cron的工作原理

后台的核心组件是cron守护进程,名为crond。它的主要工作是检查计划任务,并在指定时间到达时执行它们。

守护进程每分钟唤醒一次,检查crontab文件或基于目录的配置中的任务。这自然引出了Cron操作设置的下一个关键方面——它使用文件和目录。

Cron文件和目录

Crontab文件是Cron作业调度系统的核心。“Crontab”代表“cron表”,因为这些文件包含了在预定时间运行的命令列表。

每个crontab文件中的一行代表一个单独的作业,并包括何时运行作业的信息,随后是将被执行的命令。

从本质上讲,crontab文件有两种变体:那些属于个人用户的和系统范围的“/etc/crontab”。以下是你应该知道的关于两者的关键细节。

但在此之前,有一件重要的事情需要澄清。属于个人用户的cron文件并不保存在他们的主目录中,而是位于“/var/spool/cron”目录。同时,系统服务和应用程序的cron作业文件通常放置在“/etc/cron.d”。

用户Crontabs

用户crontabs是每个系统上用户的个人文件。用户可以拥有自己的crontab文件,以在其用户ID下安排任务。

用户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

Cron作业的结构

让我们深入每个组件:

分钟(0-59)

该字段指定命令将运行的分钟。它可以是0到59之间的值。例如,将其设置为0将在小时开始时运行命令。

小时(0-23)

小时字段以24小时格式指定。它确定一天中命令执行的小时。例如,将其设置为14将在下午2点运行命令。

月份中的日期(1-31)

该字段指定命令将运行的月份中的日期。它可以是1到31之间的任何值,具体取决于月份的天数。例如,将其设置为1将在每个月的第一天运行命令。

月份(1-12)

月份字段确定命令将执行的月份。它可以是1(一月)到12(十二月)的值。例如,将其设置为12将执行十二月的命令。

星期中的日期(0-6)

该字段指定命令应该运行的一周中的哪一天。它可以是0(星期日)到6(星期六)的值。例如,将其设置为5将每个星期五运行命令。

命令或脚本

最后,命令或脚本字段是你指定Cron作业应该执行什么操作的地方。这可以是任何命令或脚本文件的路径,Cron守护进程将在指定时间执行。

Cron语法中的特别字符

Cron语法还支持特别字符来指定更复杂的调度模式:

  • 星号(*):代表“每个”时间单位。例如,小时字段中的“*”意味着“每小时”。
  • 逗号(,):允许指定值的列表。例如,星期中的日期字段中的“1,3,5”意味着“在星期一、星期三和星期五运行。”
  • 连字符(-):指定值的范围。例如,小时字段中的“9-17”意味着“从上午9点到下午5点每小时。”
  • 斜杠(/):指定增量。例如,分钟字段中的“*/10”意味着“每10分钟。”

除了这些,Cron作业还有特别的快捷字符串,可以替换时间和日期的五个字段。这些快捷方式提供了一种快速指定与数字表示相同的计划的方法。

字符串含义
@reboot在系统启动时运行指定的命令一次。
@yearly, @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运行cron作业。这等同于在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作业的标准方式。执行时,它通过打开运行命令的用户的用户crontab文件,在系统设置的默认文本编辑器中进行编辑,例如Vi、Nano


当然,以下是继续的Cron作业中文翻译:

创建用户Cron作业

如果你首次使用该命令,可能需要先选择一个编辑器。

img 选择Crontab编辑器

接下来,要添加Cron作业,只需在crontab文件中按照上述语法添加新行。例如,我们将安排一个名为“backup.sh”的备份脚本,位于我们用户的主目录,每天凌晨3:00运行,通过添加以下行:

0 3 * * * /home/linuxiac/backup.sh

img 创建Cron作业

文件开头带有“#”符号的多行注释提供了设置Cron作业的简洁指南。按照上图所示,在它们之后输入你的作业。

然后,保存并退出编辑器。记住,Cron服务会自动检查crontab文件的更改,并相应地应用它们,所以你不需要在更改后重启它。

最后,值得注意的是,使用crontab -e在保存并退出文件时自动检查语法。Cron会在检测到任何错误时提醒你,为防止意外输入无效的Cron作业提供了宝贵的保障。

创建系统范围的Cron作业

由于crontab -e专注于个人用户crontabs,它不适用于可能需要某些管理任务的系统范围Cron配置更改。

如果是这种情况,直接编辑“/etc/crontab”文件为您提供了系统范围的crontab功能。与特定用户的crontabs不同,此文件可以包括系统范围的任务,并支持为每个任务指定用户,为在不同用户帐户下运行命令提供了灵活性。

例如,让我们创建一个系统范围的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

img 创建系统范围的Cron作业

这与用户Cron作业的不同之处在于,在最初的五个时间字段之后包括了一个额外的列。此列允许指定作业将执行的用户账户——在本例中为root。

然而,直接编辑“/etc/crontab”文件有两个主要缺点。首先,这种方法不提供语法检查,增加了错误的风险。

第二个原因是因为“/etc/crontab”影响整个系统;错误的条目可能会有广泛的影响,可能影响系统稳定性或安全性。所以,谨慎使用。

列出用户Cron作业

为确保你的Cron作业已正确安排,你可以使用以下命令显示你的用户crontab文件内容:

crontab -l

img 列出用户的Cron作业

此命令列出了为你的用户安排的所有Cron作业,允许你验证或查看设置为运行的任务。

列出系统范围的Cron作业

正如我们已经知道的,系统范围的Cron作业存储在不同的位置,并没有列在用户的crontab中。要列出系统范围的Cron作业,你需要查看“/etc/crontab”文件和目录“/etc/cron.d/”、“/etc/cron.daily/”、“/etc/cron.hourly/”、“/etc/cron.weekly/”和“_/etc/cron.monthly/”。

你可以使用cat命令或任何文本编辑器查看这些文件。例如:

sudo cat /etc/crontab

要列出目录的内容,例如“/etc/cron.daily”,请使用:

ls /etc/cron.daily/

img 列出系统范围的Cron作业

列出其他用户的Cron作业

如果你拥有超级用户(root)权限,你可以使用crontab命令和“u”选项后跟用户名和“l”选项来列出系统上任何用户的Cron作业。例如,要列出名为“bobby”的用户的Cron作业,你将运行:

sudo crontab -u bobby -l

这个命令对于系统管理员管理多个用户帐户中的Cron作业非常有用。

编辑Cron作业

与创建类似,要编辑Cron作业,请使用以下命令在默认编辑器中打开当前用户的crontab文件:

crontab -e

当你打开crontab文件时,导航到包含要编辑的Cron作业的行,并根据需要修改计划或命令,然后保存并退出文件。

如果你需要编辑另一个用户的crontab文件(假设你拥有必要的权限),例如用户“bobby”,请使用:

sudo crontab -u bobby -e

删除Cron作业

根据你的目标,你有几种方法可以删除Cron作业。要删除特定的作业,请使用crontab -e命令打开crontab文件。

从那里,导航到表示你想要删除的作业的行。通过完全删除它来删除该行。同时,小心保持所有其他行不变。之后,保存你的更改并退出编辑器。

然而,如果你希望删除一个用户的所有预定Cron作业,你可以删除该用户的crontab文件。这个操作将擦除所有预定的任务,所以应该谨慎进行。

打开终端并输入以下命令:

crontab -r

删除用户的crontab

这将删除当前用户的crontab文件,没有确认提示,所以在执行之前确保你想要继续。

如果你希望在删除之前收到确认提示,请使用命令crontab -i后跟-r。这将在删除crontab文件之前询问确认。

Crontab备忘单

为了总结上面讨论的crontab命令的主要选项,它们在下面的表中简要概述。

命令描述
crontab -e编辑crontab文件,或者如果它不存在就创建一个。
crontab -l显示crontab文件的内容。
crontab -r移除整个crontab文件。
crontab -u user与额外的选项配对使用时,此功能可以修改或查看用户的crontab文件,这是专门保留给具有管理员权限的用户的功能。

如何排查Cron作业

不幸的是,当Cron作业未能运行时,这可能是令人沮丧的,并且根据任务的性质,可能会有问题。因此,这里有一些基本的指导方针,用于调查这个问题的原因。

排查的第一步是确保Cron作业正确定义。验证每个字段是否根据你的要求正确指定。一个常见的错误是语法不正确或误解Cron如何解释特殊字符和范围。

然后,确保Cron守护进程在系统上运行。你可以通过运行如下命令来检查:

sudo systemctl status cron

检查Cron服务是否正在运行。

确保Cron作业尝试运行的脚本或命令具有适当的权限,并且你使用了绝对路径。Cron作业在有限的环境中运行,定义了最小的PATH,因此指定任何命令或脚本的完整路径至关重要。

此外,文件必须是可执行的,并且可以被Cron作业计划使用的用户访问。尝试使用Cron作业使用的相同用户帐户从命令行手动运行命令或脚本。

这可以帮助你验证命令是否按预期工作,而不是在Cron环境中。如果命令失败,你就会知道问题在于命令或脚本,而不是Cron。

记住,Cron作业在一个非交互式、非登录shell环境中运行,这意味着它们可能无法访问与手动运行命令时相同的环境变量。

如果你的脚本依赖于环境变量,你可能需要在脚本开头或Cron作业定义中显式设置它们。

最后,我们将提供几个Cron作业示例,涵盖几乎所有可能的Cron语法情况。将这些作为创建你自己的基础。

命令解释
* * * * *每分钟运行Cron作业。
0 * * * *每小时运行Cron作业。
0 0 * * *每天午夜运行Cron作业。
0 2 * * *每天凌晨2点运行Cron作业。
0 0 15 * *每月15日午夜运行Cron作业。
0 0 * * 6周六午夜运行Cron作业。
0 15 * * 1-5每天下午3点从周一到周五运行Cron作业。
*/5 * * * *每5分钟运行Cron作业。
0 8-16 * * *每天从上午8点到下午4点每小时准时执行Cron作业。
0 4 * * 2,4周二和周四凌晨4点运行Cron作业。
@reboot系统启动时运行Cron作业。

此外,像这样这样这样crontab执行时间计算(译者提供)的在线工具提供了强大的基于Web的界面来设置Cron任务。

最佳实践和技巧

  • 在使用Cron安排之前,手动测试你的脚本以确保它们按预期工作。
  • 在crontab文件中对命令和脚本使用绝对路径以避免路径问题。
  • 将输出重定向到文件或邮件,以捕获任何输出或错误进行故障排除(例如,“command > /path/to/logfile 2>&1”)。这样,你可以查看日志文件中的任何问题。
  • 在安排作业时,注意系统负载,特别是如果它们是资源密集型的,或者如果你在相同时间安排了许多作业。

结论

Cron作业对Linux系统管理至关重要。它们提供了一个强大而多功能的工具,用于调度和自动化任务。

它的美妙之处在于其多功能性和精确性。从每分钟执行的简单命令到特定日期和时间安排的复杂脚本,cron适应了许多需求。

通过用户和系统范围的crontab文件以及用于周期性任务的指定目录,Cron作业为个人用户和系统管理员提供了灵活性,以根据他们的特定需求定制任务调度。

通过利用本文的见解和示例,你将很好地实现调度成功,提高生产力,并在Linux之旅中开启新的可能性。

有关更多详细信息,cron和crontab手册页包含有关cron系统如何工作的详尽信息和解释。

感谢你的时间!你的反馈和评论一如既往地非常欢迎。