第 8 章 · 04 `crontab`:传统定时任务


文档摘要

第 8 章 · 04 :传统定时任务 本节摘要:上一节讲了现代化的 ,这一节讲它仍在广泛使用的前辈—— 。cron 是 Unix 世界最古老的定时任务机制:用一条「五段式时间表达式」声明「什么时候跑什么命令」。本节要把这个表达式彻底讲清——怎么读、怎么写「每天凌晨3点」「每15分钟」「每月1号」这类常见规则。还要讲 cron 在生产中的几个经典坑(环境变量缺失、路径不全、输出无处去),让你写的定时任务真正可靠。 内容来源:综合 cron 与 知识整理,套用体系化模板。 学习目标 阅读完本节,你应当能够: 读懂五段式时间表达式(分 时 日 月 周),写出常见规则。 用 (编辑)、 (列出)、 (删除)管理自己的定时任务。 说清每段的取值范围与特殊符号( 任意、 列表、 范围、 步长)。

第 8 章 · 04 crontab:传统定时任务

本节摘要:上一节讲了现代化的 .timer,这一节讲它仍在广泛使用的前辈——crontab。cron 是 Unix 世界最古老的定时任务机制:用一条「五段式时间表达式」声明「什么时候跑什么命令」。本节要把这个表达式彻底讲清——怎么读、怎么写「每天凌晨3点」「每15分钟」「每月1号」这类常见规则。还要讲 cron 在生产中的几个经典坑(环境变量缺失、路径不全、输出无处去),让你写的定时任务真正可靠。

内容来源:综合 cron 与 crontab 知识整理,套用体系化模板。

学习目标

阅读完本节,你应当能够:

  1. 读懂五段式时间表达式(分 时 日 月 周),写出常见规则。
  2. crontab -e(编辑)、-l(列出)、-r(删除)管理自己的定时任务。
  3. 说清每段的取值范围与特殊符号(* 任意、, 列表、- 范围、/ 步长)。
  4. 避免 cron 的经典坑:环境变量缺失、绝对路径、输出重定向。
  5. 区分用户级 crontab 与系统级 /etc/crontab//etc/cron.d/

一、设计动机:cron 的简洁与它的代价

cron 的设计极简:一个文本文件,每行一条规则,格式是「五段时间 + 要跑的命令」:

分 时 日 月 周 命令

这种简洁是 cron 的优点(易学易记),但也带来了几个坑——它跑的命令处于一个极简的环境(没有你登录 Shell 的那些环境变量、PATH 不全),输出默认发邮件(如果没有 mail agent 就丢)。这些坑让无数新手写的 cron 任务「手动跑没问题,定时跑就失败」。理解 cron 的表达式不难,难的是避开这些环境坑。

二、五段式时间表达式

* * * * * 命令 │ │ │ │ │ │ │ │ │ └─ 周(0-7, 0和7都是周日) │ │ │ └──── 月(1-12) │ │ └─────── 日(1-31) │ └────────── 时(0-23) └───────────── 分(0-59)

每段可用四种符号:

  • * —— 任意值(「每个」)
  • , —— 列表(「这些值」),如 1,15
  • - —— 范围,如 1-5
  • / —— 步长,如 */15(每15)、1-30/10(1到30每10)

经典规则示例

表达式 含义
0 3 * * * 每天 3:00
*/15 * * * * 每 15 分钟(0,15,30,45)
0 * * * * 每小时整点
0 0 * * 0 每周日 0:00(每周一次)
0 0 1 * * 每月 1 号 0:00(每月一次)
30 8 * * 1-5 周一到周五 8:30(工作日)
0 0,12 * * * 每天 0:00 和 12:00

在线生成器

记不住时,用搜索引擎搜「crontab guru」这类在线工具,可视化生成表达式。但常见规则应该背下来。

三、高频组合与实战

用户级 crontab

crontab -e # 编辑当前用户的 crontab(默认用 vi, 可改 EDITOR) crontab -l # 列出当前用户的定时任务 crontab -r # 删除当前用户的所有任务(危险!)

编辑时每行一条规则:

# 每天凌晨 3 点跑备份脚本 0 3 * * * /home/user/backup.sh >> /home/user/backup.log 2>&1 # 每 15 分钟同步一次 */15 * * * * /home/user/sync.sh

系统级定时任务

系统管理员用的两种方式:

# 方式 1: /etc/crontab(带用户名那列) # 分 时 日 月 周 用户 命令 0 3 * * * root /opt/backup.sh # 方式 2: /etc/cron.d/xxx(推荐, 一个文件一个任务包) # 格式同 /etc/crontab(带用户列)

/etc/cron.d/ 的好处:每个任务一个独立文件,便于脚本管理(部署/卸载只是复制/删除文件)。

四、踩坑与排错(cron 的经典坑)

坑 1:环境变量缺失(头号坑)

# crontab 里写: 0 3 * * * myapp --config=$APP_HOME/config.yml # 失败! cron 环境里没有 APP_HOME, 也没有你的 .bashrc

cron 跑的命令只有极简的 PATH 和几个变量,不加载你的 .bashrc/.profile。解决:

  • crontab 顶部自己定义变量:APP_HOME=/home/user/myapp
  • 命令里用绝对路径(/home/user/myapp 而非 $APP_HOME)。
  • 在脚本开头 source ~/.bashrc(若依赖其中变量)。

坑 2:命令找不到(PATH 不全)

0 3 * * * docker backup ... # 失败! cron 的 PATH 没有 docker 0 3 * * * /usr/bin/docker backup ... # 用绝对路径!

cron 的 PATH 通常只有 /usr/bin:/bin,很多程序在 /usr/local/bin/opt/...cron 里的命令一律用绝对路径,或在 crontab 顶部 PATH=/usr/local/bin:/usr/bin:/bin

坑 3:输出无处去(悄悄失败)

0 3 * * * myscript.sh # 输出默认发邮件! 没装 mail 就丢, 错误也丢 0 3 * * * myscript.sh >> /var/log/myscript.log 2>&1 # 重定向到文件!

cron 默认把命令的 stdout/stderr 发邮件给用户。没装 mail agent 时,邮件堆积(占磁盘)且你看不到错误。始终 >> log 2>&1 重定向到文件,才能排查问题。

坑 4:脚本本身没有解释器行

0 3 * * * /home/user/backup.sh # backup.sh 没有 #!/bin/bash? # cron 可能用 sh 而非 bash 执行, bash 语法报错

确保脚本第一行有 #!/bin/bash(或对应解释器),否则 cron 用默认 sh(可能是 dash)执行,bash 特有语法会失败。

本节要点回顾

  1. 五段式时间表达式:分 时 日 月 周;符号 *(任意),(列表)-(范围)/(步长)。
  2. 常见规则:每天3点 0 3 * * *、每15分钟 */15 * * * *、每周日 0 0 * * 0、每月1号 0 0 1 * *、工作日 30 8 * * 1-5
  3. 用户级 crontab -e/-l/-r;系统级 /etc/crontab/etc/cron.d/(带用户列,推荐后者)。
  4. 四大经典坑:环境变量缺失、PATH 不全(用绝对路径)、输出无处去(>> log 2>&1)、脚本无 #!/bin/bash
  5. 新系统可考虑 .timer 替代(日志集成、错过补偿),但 cron 仍广泛使用,必须会。

下一节讲一次性定时任务——at,它与 cron(周期)互补,适合「明天提醒」这类单次任务。


发布者: 作者: 灏天文库 转发
评论区 (0)
U