DevToolBox免费
博客

Cron表达式生成器与解析器:语法、示例和代码指南

17分钟阅读作者 DevToolBox

无论你是自动化服务器维护、调度数据管道,还是触发 CI/CD 工作流,cron 表达式都是基于时间的任务调度的通用语言。Cron 表达式生成器帮助你可视化构建这些调度模式,而 cron 解析器0 */6 * * 1-5 这样的加密字符串翻译为人类可读的描述。本综合指南涵盖了从经典的五字段 cron 语法到 JavaScript、Python、Bash 和云平台的实际 cron 任务示例。如果你需要快速创建或解码 cron 调度,请试用我们的免费工具。

立即试用我们的免费在线 Cron 表达式生成器和解析器工具。

什么是 Cron 表达式?

Cron 表达式是一种紧凑的字符串,用于定义自动化任务的循环调度。名称来源于希腊语 chronos(时间)和 Unix cron 守护进程,自 1970 年代以来它一直在类 Unix 系统上执行定时任务。cron 最初由 Ken Thompson 为 Version 7 Unix 创建,已成为跨操作系统、编程语言和云平台的任务调度事实标准。

在经典的 Unix crontab 格式中,cron 表达式由五个空格分隔的字段组成:分钟 小时 日 月 星期。每个字段接受数字、通配符 (*)、范围、列表和步长值。例如 30 9 * * 1-5 表示"每个工作日的 09:30"。crontab 文件(cron table 的缩写)是用户存储这些表达式及待执行命令的地方。

如今,cron 表达式已远远超越传统 Unix 系统。Kubernetes CronJob 用它调度容器化工作负载,GitHub Actions 在工作流 schedule 触发器中使用它,AWS EventBridge 支持基于 cron 的调度规则,Vercel cron 让你按计划触发无服务器函数。理解 cron 语法是每位开发者和 DevOps 工程师的必备技能。

Cron 表达式语法详解

标准 cron 表达式使用五个字段。每个字段代表一个时间单位,决定 cron 任务何时触发。以下是完整解析:

字段允许值特殊字符说明
分钟0-59* , - /任务运行的分钟
小时0-23* , - /24小时制的小时
1-31* , - / ? L W月中的第几天
1-12 或 JAN-DEC* , - /年中的月份
星期0-7 或 SUN-SAT* , - / ? L #星期几(0和7均为周日)

特殊字符说明:星号 * 匹配该字段的所有可能值。逗号 , 分隔值列表。连字符 - 定义范围。斜杠 / 定义步长值(如分钟字段的 */5 表示每5分钟)。问号 ? 在某些实现中用于日和星期字段,表示"无特定值"。

整体格式:分钟 小时 日 月 星期,即 * * * * *。这个五字段模式是每个 cron 调度定义的核心。

Cron 表达式示例表

以下是生产系统中最常见的 cron 任务示例。使用此表作为构建 cron 调度的快速参考:

Cron 表达式说明
* * * * *每分钟
*/5 * * * *每5分钟
*/15 * * * *每15分钟
0 * * * *每小时
0 */6 * * *每6小时
0 0 * * *每天午夜
0 9 * * 1-5工作日上午9点
0 0 1 * *每月1号午夜
0 0 1 1 *每年1月1号午夜
0 0 1 */3 *每季度第一天

Cron 任务代码示例

JavaScript / Node.js Cron 任务

Node.js 提供多个优秀的 cron 任务调度库。最流行的选项包括 node-croncron npm 包、零依赖的 croner 以及基于 worker 线程的 Bree

// ===== node-cron (most popular) =====
// npm install node-cron
const cron = require('node-cron');

// Run every 5 minutes
cron.schedule('*/5 * * * *', () => {
  console.log('Running task every 5 minutes');
  // Your task logic here
});

// Run weekdays at 9:00 AM
cron.schedule('0 9 * * 1-5', () => {
  console.log('Good morning! Running weekday task.');
}, {
  timezone: 'America/New_York'
});

// Validate a cron expression
console.log(cron.validate('*/5 * * * *')); // true
console.log(cron.validate('60 * * * *'));  // false

// ===== cron npm package =====
// npm install cron
const { CronJob } = require('cron');

const job = new CronJob(
  '0 */6 * * *',   // every 6 hours
  function () {
    console.log('Running every 6 hours');
  },
  null,             // onComplete
  true,             // start immediately
  'America/Chicago' // timezone
);

// ===== croner (modern, zero-dependency) =====
// npm install croner
import { Cron } from 'croner';

// Run every minute
const task = new Cron('* * * * *', () => {
  console.log('Tick every minute');
});

// Run at specific time, get next run
const next = task.nextRun();
console.log('Next execution:', next);

// Stop the job
task.stop();

// ===== Bree (worker-thread scheduler) =====
// npm install bree
const Bree = require('bree');

const bree = new Bree({
  jobs: [
    {
      name: 'backup',
      cron: '0 2 * * *',   // daily at 2 AM
      path: './jobs/backup.js'
    },
    {
      name: 'cleanup',
      cron: '0 0 * * 0',   // weekly on Sunday
      path: './jobs/cleanup.js'
    }
  ]
});

bree.start();

Python Cron 任务调度

Python 提供多种 cron 任务调度方式。schedule 库提供人性化 API,APScheduler 提供企业级功能,python-crontab 直接操作系统 crontab 文件:

# ===== schedule library (human-friendly) =====
# pip install schedule
import schedule
import time

def backup_database():
    print("Backing up database...")

def send_report():
    print("Sending daily report...")

schedule.every(5).minutes.do(backup_database)
schedule.every().day.at("09:00").do(send_report)
schedule.every().monday.at("08:30").do(send_report)

while True:
    schedule.run_pending()
    time.sleep(1)

# ===== APScheduler (enterprise-grade) =====
# pip install apscheduler
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger

scheduler = BlockingScheduler()

# Using cron expression syntax
@scheduler.scheduled_job(CronTrigger.from_crontab('*/10 * * * *'))
def cleanup_temp_files():
    print("Cleaning temp files every 10 minutes")

# Using keyword arguments
@scheduler.scheduled_job('cron', hour=9, minute=0, day_of_week='mon-fri')
def weekday_report():
    print("Weekday report at 9:00 AM")

# First Monday of each month at 3 AM
@scheduler.scheduled_job('cron', day='1-7', day_of_week='mon', hour=3)
def monthly_audit():
    print("Monthly audit")

scheduler.start()

# ===== python-crontab (manage system crontab) =====
# pip install python-crontab
from crontab import CronTab

cron = CronTab(user='myuser')

# Create a new cron job
job = cron.new(
    command='/usr/bin/python3 /opt/app/backup.py >> /var/log/backup.log 2>&1'
)
job.setall('0 2 * * *')  # Daily at 2 AM
job.set_comment('Nightly database backup')
job.enable()

# List all cron jobs
for job in cron:
    print(f"{job.slices} -> {job.command}")

cron.write()  # Save changes

# ===== Celery Beat (distributed scheduling) =====
# pip install celery
# celeryconfig.py
from celery.schedules import crontab

beat_schedule = {
    'cleanup-every-hour': {
        'task': 'tasks.cleanup',
        'schedule': crontab(minute=0, hour='*/1'),
    },
    'weekly-report': {
        'task': 'tasks.send_report',
        'schedule': crontab(hour=9, minute=0, day_of_week=1),
    },
}

Bash / Linux Crontab 命令

在 Linux 和 macOS 上,crontab 命令是管理 cron 任务的主要方式。crontab -e 编辑用户 crontab,crontab -l 列出当前任务:

# ===== Essential crontab commands =====

# Edit your user crontab
crontab -e

# List current cron jobs
crontab -l

# Remove all cron jobs (use with caution!)
crontab -r

# Edit another user's crontab (requires root)
sudo crontab -u www-data -e

# ===== Example crontab file =====
# Set environment variables at the top
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin
MAILTO=admin@example.com
TZ=UTC

# m h dom mon dow  command

# Backup database every night at 2 AM
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Run cleanup every 15 minutes with flock
*/15 * * * * flock -n /tmp/cleanup.lock /opt/scripts/cleanup.sh

# Send report on weekdays at 9 AM
0 9 * * 1-5 /opt/scripts/daily-report.sh 2>&1 | logger -t daily-report

# Rotate logs on the 1st of each month
0 0 1 * * /usr/sbin/logrotate /etc/logrotate.conf

# Health check every minute (ping monitoring service)
* * * * * curl -fsS --retry 3 https://hc-ping.com/your-uuid > /dev/null

# ===== System crontab (/etc/cron.d/) =====
# /etc/cron.d/myapp (includes username field)
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin

# Note: system crontab includes a user field
*/5 * * * * www-data /opt/myapp/cron/process-queue.sh
0 3 * * * root /opt/myapp/cron/maintenance.sh

# ===== Logging best practices =====

# Log with timestamp
0 * * * * /opt/scripts/job.sh 2>&1 | while read line; do \
  echo "$(date '+\%Y-\%m-\%d \%H:\%M:\%S') $line"; \
done >> /var/log/myjob.log

# MAILTO for error notifications
MAILTO=ops-team@example.com
# Only errors are emailed (stdout goes to log, stderr to email)
0 */6 * * * /opt/scripts/etl.sh >> /var/log/etl.log

云平台与 CI/CD Cron 调度

Cron 表达式驱动所有主要云和 CI/CD 平台的定时自动化。GitHub Actions、AWS EventBridge、Kubernetes CronJob 和 Vercel cron 都使用 cron 表达式:

# ===== GitHub Actions scheduled workflow =====
# .github/workflows/scheduled.yml
name: Scheduled Tasks
on:
  schedule:
    # Run every day at 6 AM UTC
    - cron: '0 6 * * *'
    # Run every Monday at 9 AM UTC
    - cron: '0 9 * * 1'
  workflow_dispatch: # Allow manual trigger

jobs:
  daily-task:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/daily-task.sh

---
# ===== AWS EventBridge (CloudWatch) cron =====
# Note: AWS cron has 6 fields (includes year)
# Format: minute hour day-of-month month day-of-week year

# Every 5 minutes
aws events put-rule \
  --name "every-5-min" \
  --schedule-expression "cron(*/5 * * * ? *)"

# Weekdays at 9 AM UTC
aws events put-rule \
  --name "weekday-morning" \
  --schedule-expression "cron(0 9 ? * MON-FRI *)"

# First day of each quarter
aws events put-rule \
  --name "quarterly" \
  --schedule-expression "cron(0 0 1 1,4,7,10 ? *)"

---
# ===== Kubernetes CronJob =====
# k8s-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: database-backup
spec:
  schedule: "0 2 * * *"           # Daily at 2 AM
  timeZone: "America/New_York"    # Available since k8s 1.27
  concurrencyPolicy: Forbid       # Prevent overlapping runs
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: myapp/backup:latest
            command: ["/bin/sh", "-c", "./backup.sh"]
            env:
            - name: DB_HOST
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: host
          restartPolicy: OnFailure

---
# ===== Vercel cron (vercel.json) =====
{
  "crons": [
    {
      "path": "/api/cron/daily-cleanup",
      "schedule": "0 0 * * *"
    },
    {
      "path": "/api/cron/hourly-sync",
      "schedule": "0 * * * *"
    },
    {
      "path": "/api/cron/weekly-report",
      "schedule": "0 9 * * 1"
    }
  ]
}

高级 Cron 特性

虽然标准五字段 cron 表达式满足大部分调度需求,许多实现扩展了语法。最常见的扩展是在分钟字段前添加秒字段(6字段格式):秒 分 时 日 月 星期。Quartz、node-cron 和 Spring Framework 支持此扩展格式。

扩展特殊字符L 表示"最后"——日字段中的 L 表示月末最后一天。W 表示"最近工作日"——15W 表示最接近15号的工作日。# 指定星期几的第N次出现——2#3 表示每月第三个星期一。

非标准简写表达式@reboot 系统启动时执行;@yearly 等同于 0 0 1 1 *@monthly 等同于 0 0 1 * *@weekly 等同于 0 0 * * 0@daily 等同于 0 0 * * *@hourly 等同于 0 * * * *

Cron 任务调试与监控

时区问题是 cron 任务失败最常见的原因。默认情况下 cron 使用系统时区。始终在 crontab 中显式设置 TZ=UTC 以避免夏令时变化带来的意外。

PATH 和环境变量问题:cron 守护进程以最小化环境运行任务。默认 PATH 通常只有 /usr/bin:/bin。通过在 crontab 顶部设置 PATH 或使用绝对路径来解决。

输出未捕获:默认情况下 cron 尝试通过本地邮件系统发送输出。始终将 stdout 和 stderr 重定向到日志文件:0 * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1

任务重叠执行:如果 cron 任务执行时间超过间隔,可能同时运行多个实例。使用 flock 锁文件机制防止重叠执行。监控工具如 healthchecks.io 可在任务失败时发出警报。

Cron 任务最佳实践

使用描述性注释:在每个 crontab 条目上方添加注释说明任务用途、负责人和最后修改时间。

重定向输出并使用日志:始终将输出重定向到专用日志文件,使用 logrotate 防止日志无限增长。

使用 flock 实现互斥:使用 flock -n /tmp/myjob.lock /path/to/script.sh 防止重叠运行。

显式设置 SHELL 和 PATH:在 crontab 顶部声明 SHELL=/bin/bash 和完整的 PATH。

使用绝对路径:在 cron 任务中始终使用脚本、二进制文件和配置文件的绝对路径。

使用专业监控服务:使用 healthchecks.io、Cronitor 等服务跟踪任务执行。在脚本末尾添加 curl 调用以发送心跳。

注意时区:记录 cron 任务期望的时区。使用 TZ=UTC 保持跨环境一致性。注意夏令时切换可能导致凌晨 2-3 点的任务被跳过或重复执行。

常见问题

Cron 表达式的五个字段分别代表什么?

标准 cron 表达式的五个字段从左到右分别是:分钟(0-59)、小时(0-23)、月中日(1-31)、月份(1-12)、星期(0-7,0和7都是周日)。每个字段接受精确值、通配符(*)、范围(1-5)、列表(1,3,5)和步长值(*/5)。

Cron 和 systemd timer 有什么区别?

Cron 是使用 crontab 文件的传统 Unix 任务调度器。Systemd timer 是 Linux 上使用 systemd 的现代替代方案。主要区别:systemd timer 可基于事件触发、支持更自然的日历语法、能处理错过的运行、集成 systemd 日志。但 cron 表达式仍是云平台的标准。

如何让 cron 任务每 N 分钟运行一次?

使用分钟字段的步长语法 */N。例如:每5分钟 = "*/5 * * * *",每10分钟 = "*/10 * * * *",每15分钟 = "*/15 * * * *"。注意步长值应能整除60以获得一致间隔。

相关指南:

掌握 cron 表达式是每位需要可靠定时自动化的开发者和运维工程师的必备技能。从基本的 Unix crontab 配置到 Kubernetes 和 GitHub Actions 的云原生 cron 调度,五字段 cron 语法是通用技能。收藏本指南作为综合参考。

使用我们的免费在线工具即时生成和解析 Cron 表达式。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

Cron Expression ParserCron Expression Generator⏲️Crontab Generator🔍Cron Expression Parser

相关文章

Cron 表达式实例:每 5 分钟、每天、每周、每月

通过实用示例掌握 cron 表达式。学习如何设置每 5 分钟、每小时、每天、每周和每月的定时任务。

Serverless 平台的 Cron 调度:GitHub Actions、Vercel Cron 和 Cloudflare Workers

掌握各 Serverless 平台的 Cron 表达式,了解语法差异、时区陷阱和实用调度示例。

Docker Compose 速查表:服务、卷和网络

Docker Compose 核心参考:服务定义、卷挂载、网络配置、环境变量和常见栈示例。