Skip to content
返回博客
教程

Crontab 速查表:50+ Cron 表达式与现代调度器完全指南

可直接复制的 Crontab 速查表:50+ cron 表达式、五字段语法详解、星期/日期 OR 陷阱、时区调试,附 Kubernetes / GitHub Actions / AWS EventBridge 对比。

13 分钟

Crontab 速查表:50+ Cron 表达式、语法详解与现代调度器完全指南

cron 表达式由五个字段加一条命令组成:分、时、日、月、星期。这套语法从 1979 年起驱动 Unix 任务调度,现在也驱动 Kubernetes CronJob、GitHub Actions、AWS EventBridge 和 Vercel cron 触发器。学一次就够用了。

这篇文章面向当下就要写表达式的开发者:一个 Linux 定时任务,一个 Kubernetes CronJob,一个 GitHub Actions 触发器,或者排查为什么本该每五分钟跑一次的任务只在整点触发。直接看下面的快速参考表复制表达式;想看字段规则就跳到「语法详解」;或者打开 Crontab 生成器 — Cron 表达式构建与解析 —— 一个在浏览器中运行的隐私优先的 crontab guru 替代工具 —— 实时验证。

Cron 表达式快速参考表

下面三十个表达式覆盖了约 90% 的真实调度需求。每一条都是合法的 POSIX 五字段 cron,可直接粘贴到 crontab -e、Kubernetes 的 schedule: 或 GitHub Actions 的 cron: 中。

调度场景Cron 表达式中文解释
每分钟* * * * *全天每一分钟
每 5 分钟*/5 * * * *第 0、5、10、…、55 分钟
每 15 分钟*/15 * * * *第 0、15、30、45 分钟
每 30 分钟*/30 * * * *第 0 和第 30 分钟
每小时0 * * * *每个整点
每 2 小时0 */2 * * *第 0、2、4、…、22 时
每 6 小时0 */6 * * *第 0、6、12、18 时
每天两次(早 9 + 晚 9)0 9,21 * * *9 点和 21 点整
工作日每天上午 9 点0 9 * * 1-5周一至周五 09:00
周末每天上午 9 点0 9 * * 0,6周六周日 09:00
每天午夜0 0 * * *每日 00:00
每天凌晨 2:3030 2 * * *低峰批处理窗口
每周一上午 9 点0 9 * * 1周一 09:00
每周五下午 5 点0 17 * * 5周五 17:00
每周日午夜0 0 * * 0等价于 @weekly
每月 1 号午夜0 0 1 * *每月 1 日 00:00,等价于 @monthly
每月 15 号中午0 12 15 * *月中发薪窗口
每月最后一天(需 wrapper)0 0 28-31 * * + 脚本需要日期判断
每季度(1/4/7/10 月 1 日)0 0 1 JAN,APR,JUL,OCT *每季度第一天
每年(1 月 1 日)0 0 1 1 *@yearly元旦零点
工作日 9-17 点每 5 分钟*/5 9-17 * * 1-5工作时间轮询
周末每 30 分钟*/30 * * * 0,6周六周日监控
每小时两次,15 和 45 分15,45 * * * *错开整点高峰
每月第一个周一(需 wrapper)0 9 1-7 * 1 + AND 判断需 wrapper(见下文)
@hourly @daily @weekly @monthly @yearly非标准,但被广泛支持
仅在重启时@reboot非标准,仅 vixie cron 支持

把上面任意一条粘贴到 Crontab 生成器 — Cron 表达式构建与解析,可以预览接下来五次触发时间,是上线前最快的烟雾测试。

Cron 语法详解:五个字段

cron 表达式是由空格分隔的五个字段,再加一条命令。每个字段控制调度的一个维度。这套语法是本文涉及到的所有调度器的共同基础。

┌──────────── minute       (0 - 59)
│ ┌────────── hour         (0 - 23)
│ │ ┌──────── day-of-month (1 - 31)
│ │ │ ┌────── month        (1 - 12 or JAN-DEC)
│ │ │ │ ┌──── day-of-week  (0 - 6 or SUN-SAT; 0 and 7 both mean Sunday)
│ │ │ │ │
* * * * *  command-to-run

记忆口诀:「分时日月周」,从左到右,由小到大。

各字段允许的取值

字段范围别名备注
0-590 表示「整点」
0-2324 小时制;0 是午夜,12 是正午
1-31当月不存在的日期会静默地永不触发(例如 2 月 31 日)
1-12JAN、FEB、MAR、…、DEC大小写不敏感
0-7SUN、MON、TUE、…、SAT07 都表示周日

运算符详解

五个运算符就能覆盖所有标准 cron 表达式:

运算符含义示例展开结果
*任意值* * * * *每分钟
,列表0 9,12,17 * * *09:00、12:00、17:00
-闭区间范围0 9-17 * * *09:00 到 17:00 每个整点
/步长*/15 * * * *第 0、15、30、45 分钟
混合组合0 9-12,14-17 * * *上午+下午,跳过午饭时间

步长运算符要小心。*/N 是相对于字段的最小值对齐的,不是相对于当前时间。*/15 的含义是「每个小时的第 0、15、30、45 分钟」,不是「从现在起每 15 分钟一次」。12:03 保存表达式,下一次触发就是 12:15。如果基数不是通配符,5/15 读作「从 5 开始,每 15 分钟一次」:第 5、20、35、50 分钟。

月份与星期使用名称

月份和星期可以写成名称,大小写不敏感:

0 0 1 JAN,APR,JUL,OCT *    # 每季度的第一天
0 9 * * MON-FRI            # 工作日上午 9 点
0 17 * * FRI               # 周五下午 5 点

代码评审时名称更易读,数字形式可移植性稍好一些。一个项目内统一风格即可。

非标准宏:@reboot@daily 及其家族

大多数 cron 实现都接受六个快捷宏:

展开为含义
@yearly / @annually0 0 1 1 *每年一次,1 月 1 日午夜
@monthly0 0 1 * *每月 1 日午夜
@weekly0 0 * * 0每周日午夜
@daily / @midnight0 0 * * *每天午夜
@hourly0 * * * *每个整点
@reboot(特殊)cron 守护进程启动时执行一次

这些宏是非标准的:vixie cron 和 cronie 支持,但 Kubernetes CronJob、GitHub Actions、AWS EventBridge 都不认。要写可移植的表达式,就写五字段形式。@reboot 在容器里几乎用不上,因为 cron 守护进程通常不是 init 进程。

50+ 可复制 Cron 表达式(按用途分组)

这一节按六个用途分桶,给出更密集的 cron 例子。

每 N 分钟

* * * * *          # 每分钟
*/2 * * * *        # 每 2 分钟
*/5 * * * *        # 每 5 分钟 —— 经典的「每 5 分钟」场景
*/10 * * * *       # 每 10 分钟
*/15 * * * *       # 每 15 分钟
*/30 * * * *       # 每 30 分钟
0,30 * * * *       # 明确指定第 0 和第 30 分钟(与 */30 等价)
*/45 * * * *       # 警告:只在第 0 和第 45 分钟触发,然后回绕

*/45 是一个常见的陷阱:分钟范围是 0-59,所以会落在第 0 和第 45 分钟,下一个小时再次回绕到第 0 分钟。要真正实现 45 分钟的等间隔节奏,需要外部 worker。

整点变体

0 * * * *          # 每小时 :00
30 * * * *         # 每小时 :30
0 */2 * * *        # 每 2 小时,偶数时刻
0 */6 * * *        # 每 6 小时
0 */12 * * *       # 每天两次,00:00 和 12:00
15 */2 * * *       # 每 2 小时,错开 15 分钟(避开整点高峰)

每天的固定时间

0 0 * * *          # 午夜(= @daily / @midnight)
30 2 * * *         # 02:30 —— 低峰批处理窗口
0 9 * * *          # 09:00
45 23 * * *        # 23:45 —— 日终汇总
0 9,12,17 * * *    # 一天三次
0 9-17 * * *       # 从 09:00 到 17:00 每个整点

每周调度

0 9 * * 1-5        # 工作日上午 9 点
0 9 * * 0,6        # 周末上午 9 点
0 18 * * 5         # 周五下午 6 点
0 0 * * 0          # 周日午夜(= @weekly)
0 9 * * MON,WED,FRI # 周一/三/五上午 9 点
*/30 9-17 * * 1-5  # 工作日工作时间每 30 分钟一次

每月与每季度

0 0 1 * *          # 每月 1 日午夜(= @monthly)
0 0 15 * *         # 每月 15 日 —— 发薪窗口
0 0 1,15 * *       # 1 日和 15 日 —— 半月节奏
0 0 1 */3 *        # 每季度:1 月、4 月、7 月、10 月的 1 日
0 0 1 JAN,APR,JUL,OCT *  # 同上,月份用名称
0 0 28-31 * *      # 月末几天 —— 搭配日期判断 wrapper

「每月最后一天」在 POSIX cron 中没有原生表达式。可以写一个 wrapper 判断 date -d tomorrow +%d = 01,或者改用原生支持该语法的调度器(Quartz 有 L,Kubernetes 没有)。

每年与宏快捷写法

0 0 1 1 *          # 1 月 1 日午夜(= @yearly / @annually)
0 0 25 12 *        # 圣诞节午夜
@yearly            # = 0 0 1 1 *
@monthly           # = 0 0 1 * *
@weekly            # = 0 0 * * 0
@daily             # = 0 0 * * *
@hourly            # = 0 * * * *
@reboot            # 特殊:守护进程启动时执行一次(仅 vixie cron)

把上面任何一条粘贴到 Crontab 生成器 — Cron 表达式构建与解析都可以查看接下来五次触发时间,是上线前最便宜的烟雾测试。

Cron vs systemd timer vs 云调度器:决策矩阵

cron 是默认选项,但不一定是最优解。下面对七种最常见的调度器做了对比。无论你在判断 cron 还是 systemd timer,对比 Kubernetes CronJob 与 Vercel cron,还是从 crontab 迁移到托管云服务,都用得上。

特性vixie cronsystemd timerK8s CronJobGHA scheduleAWS EventBridgeVercel CronCloudflare Workers
字段语法5 字段 POSIXOnCalendar 规范5 字段 POSIX + timeZone5 字段 POSIX6 字段 Quartz,含 ?5 字段 POSIX5 字段 POSIX
最小间隔1 分钟1 秒1 分钟尽力而为,建议 ≥15 分钟1 分钟1 分钟(Pro 计划)1 分钟
显式时区CRON_TZ=Persistent=truespec.timeZone(1.27+)仅 UTCScheduleExpressionTimezone仅 UTC仅 UTC
漏跑补偿否(用 anacron)是(Persistent=true是(startingDeadlineSeconds
重试 / 退避部分是(backoffLimit失败时重试
并发控制否(用 flock部分是(concurrencyPolicy
@reboot 支持是(通过 OnBootSec=

systemd timer:什么时候比 cron 更合适

在基于 systemd 的 Linux 上,timer 是一个实用的替代方案:日历式语法可读性更好,原生接入 journal,还能补漏跑。一个 timer 和对应的 service:

# daily-report.timer
[Unit]
Description=Run daily report at 9 AM
[Timer]
OnCalendar=*-*-* 09:00:00
Persistent=true
Unit=daily-report.service
[Install]
WantedBy=timers.target
# daily-report.service
[Unit]
Description=Daily report job
[Service]
Type=oneshot
ExecStart=/usr/local/bin/daily-report.sh
User=reporter

systemctl enable --now daily-report.timer 启用。最大的差异在 Persistent=true:如果 9 点机器是关机的,开机后 timer 会立即补跑。vixie cron 没有等价能力,除非额外用 anacron。关于服务侧的安全加固,参考安全最佳实践

Kubernetes CronJob

Kubernetes 在 POSIX 调度的基础上加了一层原语,用于控制并发、保留历史和指定时区:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-report
spec:
  schedule: "0 2 * * *"
  timeZone: "America/New_York"     # Kubernetes 1.27+
  concurrencyPolicy: Forbid        # never run two at once
  startingDeadlineSeconds: 300     # skip if delayed >5 min
  jobTemplate:
    spec:
      backoffLimit: 2
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: reporter
              image: reporter:1.4.0
              command: ["/usr/local/bin/report.sh"]

concurrencyPolicy: Forbid 就是你在 Kubernetes 里的 flock 等价物。不加这一项,一个跑得久的任务会和下一次触发叠在一起。所有可配项见下文「Kubernetes CronJob 字段参考」。

GitHub Actions schedule 的注意事项

GitHub Actions 接受标准的五字段 POSIX cron:

on:
  schedule:
    - cron: '0 9 * * 1-5'   # weekdays at 9 AM UTC

但这是「尽力而为」:在 GitHub runner 负载高时,任务可能延迟几分钟,甚至整次跳过。不要使用短于 15 分钟的间隔。GHA 没有时区设置,永远是 UTC。

AWS EventBridge:Quartz 风格的六字段

AWS EventBridge 使用 Quartz 变体的 cron,有六个字段,并且要求两个日字段之一必须是 ?

cron(0 9 * * ? *)

字段顺序是:Minutes Hours Day-of-month Month Day-of-week Year。当其中一个日字段有约束时,另一个必须是 ?(Quartz 用这个语法来消解 POSIX 的 OR 歧义)。从 Linux crontab 直接复制过来肯定通不过校验。

Vercel Cron、Cloudflare Workers、Render Cron Jobs

新兴的 serverless 平台统一选用了五字段 POSIX。Vercel cron job 写在 vercel.json 里:{ "crons": [{ "path": "/api/cron/nightly", "schedule": "0 2 * * *" }] }。Cloudflare Workers 的 Cron Triggers 写在 wrangler.toml 里:

[triggers]
crons = ["*/15 * * * *", "0 9 * * 1-5"]

Render 用的是 render.yaml。这三家都按 UTC 跑,并且不能为单条调度单独覆盖时区,从一开始就按 UTC 设计。

7 个 Cron 调试陷阱(以及怎么抓到它们)

绝大多数「我的 cron 没跑」的报告,根因都在下面这七个之一。怀疑调度器之前,先把这张清单走一遍。

陷阱 1:PATH 极度精简

cron 启动任务时给的是最精简的 $PATH,通常只有 /usr/bin:/bin。你交互式 shell 里有 /usr/local/bin~/.cargo/bin,还有十几条来自 .bashrc 的补充。这些 cron 一概不知道。环境变量类问题里,这一条出现得最频繁。

症状:node: command not found。修法:在 crontab 顶部显式设置 PATH,或使用绝对路径。

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin

*/15 * * * *  /usr/local/bin/poll-api.sh
0 9 * * *     /home/deploy/.cargo/bin/my-rust-cli

陷阱 2:stdout 和 stderr 被静默丢弃

默认情况下,cron 的输出送到一个没人看的邮件 spool 里。任务就这么静默失败了。把两路流都重定向:

*/15 * * * *  /usr/local/bin/job.sh >> /var/log/job.log 2>&1

JSON 输出可以管道送 jq处理;提取日志行参考正则表达式速查表。systemd timer 用 journalctl -u your-timer.service 就能看到所有输出。

陷阱 3:开发与生产时区错位

你在纽约的笔记本上写 0 9 * * *,以为是美东时间早 9 点。生产服务器跑在 UTC。cron 按 UTC 早 9 点触发,也就是美东凌晨 4 点,没人发现。修法:服务器统一用 UTC、调度按 UTC 写,或者显式锁定时区。

CRON_TZ=America/New_York
0 9 * * *  /usr/local/bin/morning-report.sh

CRON_TZ 从 vixie cron 3.0 起支持;Kubernetes 1.27+ 提供 spec.timeZone;AWS EventBridge 用 ScheduleExpressionTimezone;GitHub Actions 永远是 UTC。UTC、夏令时和 epoch 换算细节参考 Unix 时间戳完全指南

陷阱 4:命令中未转义的 %

cron 会把未转义的 % 当作换行符,后面的内容会被当成标准输入喂给命令。所以 date +"%Y-%m-%d" 直接挂掉。要把每个 % 转义成 \%,或者干脆把逻辑搬进脚本:

0 0 * * *  echo "Run at $(date +"\%Y-\%m-\%d")" >> /tmp/log

陷阱 5:执行时间重叠

一个 */5 * * * * 的任务如果偶尔跑七分钟,下一次实例就会在上一次还没结束时被启动。两个进程会在同一行数据、同一个锁文件、同一个 API 配额上互殴。用 flock 串行化:

*/5 * * * *  flock -n /tmp/job.lock /usr/local/bin/job.sh

-n 表示锁被占用时立刻退出。在 Kubernetes 里则设置 concurrencyPolicy: Forbid。锁文件的权限也得注意,参见安全最佳实践

陷阱 6:容器里的 @reboot

@reboot 在 cron 守护进程启动时跑一次。在 VM 里它对应开机时刻;在容器里 cron 守护进程通常不是 PID 1,甚至根本没在跑。容器里不要用 @reboot,把启动时跑一次的逻辑放在 entrypoint 或 init container 里。

陷阱 7:POSIX 中日与星期的 OR 语义

这是代价最高的 cron 陷阱。POSIX 规则:当日字段和星期字段都被约束(两者都不是 *)时,两者中任意一个匹配就会触发。

0 0 1 * 5 看起来像「每月 1 号的午夜,且必须是周五」,但实际上它在每月 1 号以及每个周五都会触发,每月多出六到十次。

# 错:看起来像「月初 1 号,且必须是周五才跑」
0 0 1 * 5
# 对:只保留一个约束
0 0 1 * *          # 每月 1 号
0 0 * * 5          # 每个周五
# AND 语义需要 wrapper
0 0 1-7 * 5  [ "$(date +\%u)" = "5" ] && /script    # 仅当月第一个周五

把可疑表达式粘进 Crontab 生成器 — Cron 表达式构建与解析,看接下来几次触发时间,OR 陷阱一目了然。

现代调度器:什么时候不该用 cron

cron 适合「在大致这个时间、按固定节奏跑一条命令」。下面这些相邻问题它就不擅长了:

  • 有依赖关系的工作流(先 A,A 成功后跑 B):用 Airflow、Prefect、Dagster。
  • 重试、指数退避、死信队列:用 Temporal、AWS Step Functions、Sidekiq。
  • 亚分钟级间隔:用长生命周期 worker,在迭代间 sleep。
  • 秒级精度:用专用守护进程;托管调度器都会声明不保证精确触发。
  • 事件驱动型任务:用 webhook、消息队列、CDC 流。

cron 并没有被淘汰:Airflow、Step Functions、Sidekiq 在工作流的入口都接受 cron 表达式。这套五字段语法是可复用的。

Kubernetes CronJob 字段参考

下面是 Kubernetes CronJob 语法的完整字段参考:

字段默认值作用
schedule必填POSIX 5 字段 cron 表达式
timeZone控制器所在时区显式时区(1.27+);用 IANA 名称
concurrencyPolicyAllowForbid 在上次还在跑时跳过;Replace 取消上次
startingDeadlineSeconds无限制延迟超过该秒数则跳过
successfulJobsHistoryLimit3保留多少个成功的 Job
failedJobsHistoryLimit1保留多少个失败的 Job
suspendfalse暂停但不删除
backoffLimit6标记 Job 失败前的 Pod 重试次数
activeDeadlineSeconds未设置Pod 运行时长的硬上限
ttlSecondsAfterFinished未设置Job 结束后多少秒自动删除

两个常见坑:忘掉 timeZone 会让调度跟着 kube-controller-manager 所在主机的时区跑(在托管 Kubernetes 上完全不可预测);如果是每分钟一次的调度,默认的 successfulJobsHistoryLimit: 3 会让 Job 对象按每分钟三个的速度堆积,除非配合 ttlSecondsAfterFinished 一起设置。

跨平台的 Cron 等价物

macOS launchd。Apple 推荐用 launchd 替代 cron。一个 launchd 任务是放在 ~/Library/LaunchAgents/ 下的 .plist

<plist version="1.0"><dict>
  <key>Label</key><string>com.example.daily</string>
  <key>ProgramArguments</key><array><string>/usr/local/bin/daily.sh</string></array>
  <key>StartCalendarInterval</key>
  <dict><key>Hour</key><integer>9</integer><key>Minute</key><integer>0</integer></dict>
</dict></plist>

launchctl load ~/Library/LaunchAgents/com.example.daily.plist 加载。和 cron 不同,launchd 会在睡眠/唤醒后补上漏掉的执行。

Windows 任务计划程序schtasks

schtasks /create /tn "DailyReport" /tr "C:\scripts\report.bat" /sc DAILY /st 09:00
schtasks /create /tn "EveryFifteen" /tr "C:\scripts\poll.bat" /sc MINUTE /mo 15

在 WSL 上原生 Linux cron 也能用,但会话退出就停了。要让 WSL 任务始终在线,用任务计划程序拉起。

Docker 容器里的 cron。大多数精简镜像(alpinedebian-slimdistroless)出厂不带 cron 守护进程。装一个 croniebusybox-cron,再用 tinis6-overlay 把它跑成 PID 1。不过通常更好的选择是直接用 Kubernetes CronJob。

进阶技巧与模式

每月最后一天

cron 没有原生的「最后一天」运算符。在 28-31 这几天都跑一次,再判断明天是不是 1 号:

0 23 28-31 * *  [ "$(date -d tomorrow +\%d)" = "01" ] && /usr/local/bin/eom.sh

当月第 N 个星期几

「第一个周一」用同样的 wrapper 模式,把日字段限制在 1-7,再判断星期:

0 9 1-7 * *  [ "$(date +\%u)" = "1" ] && /usr/local/bin/first-monday.sh

「最后一个周五」就把日改成 25-31 再加星期判断。

用随机偏移分散负载

当大量机器跑同一个 cron 时,0 0 * * * 会在 UTC 午夜造成 thundering herd。撒点随机延迟:

RANDOM_DELAY=10                                              # cronie / anacron,单位分钟
0 0 * * *  /usr/local/bin/job.sh

0 0 * * *  sleep $((RANDOM \% 600)); /usr/local/bin/job.sh   # 可移植写法

心跳监控

cron 是静默失败的。dead-man’s-switch 模式可以解决:任务每次成功后向监控服务发一次 ping;如果预期的 ping 没到,监控服务报警。Healthchecks.io、Cronitor、Dead Man’s Snitch 都有免费层。

*/15 * * * *  /usr/local/bin/job.sh && curl -fsS --retry 3 https://hc-ping.com/your-uuid

如果监控逻辑要根据响应码分支(200 健康、429 限流、503 降级),参考 HTTP 状态码速查表

幂等性是任务自身的属性,不是调度器的

cron 没有重试、没有漏跑补偿、没有并发控制。最可靠的修法是让任务本身可以安全地重复执行。把「上午 9 点发当日报表」重新设计为「如果今天还没发过,就发」,漏跑、重复、人工补跑最终都会收敛到同一个状态。

常见问题

*/5 * * * * 真的是每 5 分钟一次吗?

几乎是 —— */5 * * * * 对齐到第 0 分钟,而不是「从现在起每 5 分钟」。每小时在第 0、5、10、…、55 分钟触发。步长 */N 是相对于字段的最小值,而不是当前时间。12:03 保存表达式,下一次是 12:05,不是 12:08。

0 0 * * * 在 cron 里是什么意思?

0 0 * * * 表示每天午夜(00:00)按服务器本地时区执行。字段含义:分 0、时 0、任意日、任意月、任意星期。等价于宏 @daily@midnight。要锁定时区,在 crontab 顶部加 CRON_TZ=America/New_York

怎么让 cron 任务每 30 秒跑一次?

标准 POSIX cron 做不到,最小粒度是 1 分钟。三个 workaround:两个 * * * * * 任务错开排,其中一个加 sleep 30 &&;或者用 systemd timer 配 OnCalendar=*:*:0/30;或者写一个长驻 worker 在迭代间 sleep。最后这种通常是正解。

cron 默认用什么时区?

服务器的系统本地时区(/etc/timezoneTZ 环境变量)。一个写在 UTC 服务器上的 9 点 cron 会按美东凌晨 4 点跑。修法:在 crontab 顶部设置 CRON_TZ=,或者服务器统一 UTC、调度按 UTC 设计。GitHub Actions 永远是 UTC;Kubernetes 1.27+ 支持 spec.timeZone

为什么我的 cron 任务没运行?

如果 cron 任务没有运行,按顺序检查:cron 守护进程是否在跑(systemctl status cron);crontab 里是否设了 $PATH;stderr 有没有捕获(>> log 2>&1);用户的 crontab 是否真的加载了(crontab -l);命令里的 % 有没有转义;时区是否符合预期。绝大多数「没运行」的报告都卡在第二或第三条。

Kubernetes CronJob 的语法和 Linux cron 一样吗?

调度字段是一样的,两者都用 POSIX 五字段 cron。Kubernetes 额外加了 spec.timeZone(1.27+)、用于并发控制的 concurrencyPolicy、用于漏跑补偿的 startingDeadlineSeconds,以及用于暂停的 suspend: true。Linux cron 没有这些,要靠 flockanacron 凑合。

@reboot@daily 有什么区别?

@daily0 0 * * * 的宏,每天午夜按固定节奏跑。@reboot 是在 cron 守护进程启动时跑一次,没有任何周期性。@reboot 在 vixie cron 和 cronie 里支持,但在 Kubernetes CronJob、GitHub Actions 和 AWS EventBridge 里都不支持。在容器里,@reboot 也几乎不会触发。

cron 和 crontab 有什么区别?

cron 是运行计划任务的后台守护进程,crontab 是列出这些任务的文件(也是编辑该文件的 crontab 命令)。守护进程按计划读取每个用户的 crontab,运行执行时间与 cron 表达式匹配的命令。所以 cron 是引擎,crontab 是配方。