Cron 表达式详解:语法、示例和常见模式

· 12分钟阅读

Cron 是在类 Unix 操作系统上支持自动化的基于时间的作业调度器。无论您是备份数据库、发送定时邮件,还是运行维护脚本,理解 cron 表达式对于任何开发人员或系统管理员都至关重要。

这份综合指南详细介绍了关于 cron 语法您需要了解的一切,从基本模式到高级调度技术。您将学会如何自信地编写、测试和排查 cron 表达式。

目录

理解 Cron 基础

Cron 是一个在类 Unix 系统后台持续运行的守护进程,每分钟检查是否有计划执行的作业。这个名称来源于希腊语单词"chronos",意为时间。

系统上的每个用户都可以拥有自己的 crontab(cron 表)文件,其中包含计划作业。系统还在 /etc/cron.d//etc/cron.daily//etc/cron.hourly/ 等目录中维护系统级任务的 crontab。

当 cron 作业执行时,它以拥有该 crontab 的用户权限运行。这对于安全性和文件访问考虑至关重要。作业在没有常规 shell 配置的最小环境中运行,这是初学者常见的困惑来源。

专业提示:Cron 作业无法访问您的交互式 shell 环境。始终对命令和文件使用绝对路径,并在 crontab 中明确设置任何所需的环境变量。

Cron 语法:五个字段

标准 cron 表达式由五个时间和日期字段组成,后跟要执行的命令。理解这些字段是编写有效 cron 调度的基础。

┌───────────── 分钟 (0-59)
│ ┌───────────── 小时 (0-23)
│ │ ┌───────────── 月份中的日期 (1-31)
│ │ │ ┌───────────── 月份 (1-12 或 JAN-DEC)
│ │ │ │ ┌───────────── 星期几 (0-7,0 和 7 = 星期日,或 SUN-SAT)
│ │ │ │ │
* * * * * 要执行的命令

每个字段接受特定的值和特殊字符来控制作业何时运行。让我们分解每个字段代表什么:

字段 范围 特殊字符 描述
分钟 0-59 * , - / 作业运行的确切分钟
小时 0-23 * , - / 24 小时格式的小时(0 = 午夜)
月份中的日期 1-31 * , - / L W 月份中的日期
月份 1-12 或 JAN-DEC * , - / 一年中的月份(1 = 一月)
星期几 0-7 或 SUN-SAT * , - / L # 星期几(0 和 7 = 星期日)

命令字段可以是任何有效的 shell 命令、脚本路径或用分号分隔的一系列命令。cron 作业的输出通常会通过电子邮件发送给用户,除非被重定向。

特殊字符和操作符

Cron 的强大之处在于其特殊字符,它们允许灵活的调度模式。掌握这些操作符可以让您创建复杂的调度,而无需复杂的逻辑。

星号 (*) - 匹配所有值

星号是通配符字符,匹配字段的所有可能值。当您在字段中使用 * 时,作业将在该字段范围内的每个值运行。

例如,* * * * * 意味着"每个月的每一天的每小时的每分钟的每个星期几" - 换句话说,每一分钟。

逗号 (,) - 列出多个值

逗号让您指定多个离散值。当您需要特定的、非连续的时间时,这很有用。

示例:0 9,12,15,18 * * * 在每天上午 9 点、中午、下午 3 点和下午 6 点运行。

连字符 (-) - 定义范围

连字符创建包含性的值范围。这比用逗号列出许多连续值更简洁。

示例:0 9-17 * * 1-5 在周一至周五的上午 9 点到下午 5 点每小时运行(工作时间)。

斜杠 (/) - 步进值

斜杠操作符指定步进间隔。语法是 */n范围/n,其中 n 是步进值。

示例:*/15 * * * * 每 15 分钟运行一次(在 :00、:15、:30、:45)。您也可以使用范围:0-30/5 * * * * 在每小时的前半小时每 5 分钟运行一次。

扩展字符 (L, W, #)

这些是某些 cron 实现(如 Vixie cron 和 Quartz 调度器)支持的非标准扩展,但标准 Unix cron 不支持。

字符 含义 示例 描述
L 最后 0 0 L * * 每月最后一天的午夜
W 工作日 0 0 15W * * 最接近 15 号的工作日
# 第 N 次出现 0 0 * * 5#3 每月的第三个星期五

快速提示:在使用 L、W 或 # 字符之前,请验证您的 cron 实现是否支持它们。标准 Unix cron 将拒绝这些表达式。使用我们的 Cron 表达式生成器来测试兼容性。

常见 Cron 模式

以下是您在实际应用中最常遇到的 cron 模式。这些涵盖了典型自动化任务的大多数调度需求。

基本时间间隔

每日调度

每周调度

每月和每年调度

专业提示:在调度每月作业时,请注意大于 28 的月份日期值。使用 0 0 31 * * 只会在有 31 天的月份运行。对于月末作业,考虑使用上个月的最后一天或下个月的第一天。

使用我们的 Cron 表达式解析器测试和验证您的 cron 表达式,以准确查看您的作业何时运行。

高级调度技术

除了基本模式之外,您还可以组合操作符和字段来创建符合复杂业务需求的复杂调度。

组合多个条件

您可以在单个字段中使用多个操作符来创建细致的调度。例如,0 9,12,15 * * 1-5 在上午 9 点、中午和下午 3 点运行,但仅在工作日。

另一个示例:*/10 8-17 * * 1-5 每 10 分钟运行一次,但仅在工作日的工作时间(上午 8 点到下午 5 点)。

月份日期与星期几

当同时指定月份日期和星期几(不是 *)时,作业在任一条件满足时运行(OR 逻辑,而非 AND)。这是常见的困惑来源。

例如,0 0 13 * 5 在每月 13 号午夜每个星期五运行,而不仅仅是在 13 号星期五。

要专门为 13 号星期五调度某些内容,您需要使用检查两个条件的脚本:

0 0 13 * * [ $(date +\%u) -eq 5 ] && /path/to/script.sh

将步进值与范围结合使用

您可以组合范围和步进值以实现精确控制。语法 起始-结束/步进 在特定范围内按间隔运行。

示例: