⏰ 第06章 · Cron 定时任务

crontab 语法

Cron 定时任务

这一章讲 Linux 最经典的任务调度器 cron:怎么定义"哪天几点几分执行什么命令",怎么管理,怎么避免最常见的坑。你的服务器上已经有两个 cron 任务(贴吧签到、监控报告),它们就是 cron 的日常用法。

cron 是干什么的

cron 是一个后台守护进程(通常由 cron.service 托管),每分钟检查一次有没有到点的任务,到了就执行。cron 任务分两类:

  1. 用户级 crontab:用 crontab -e 编辑,属于某个用户。
  2. 系统级 cron:写在 /etc/cron.d/、/etc/crontab,或 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly(按目录划分周期)。

本机任务用 crontab -l 看到,属于 root 用户级。

crontab 语法:六个字段

* * * * *  command
│ │ │ │ │
│ │ │ │ └── 星期 (0-7,0 与 7 都表示周日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)

常用时间写法

表达式 含义
* * * * * 每一分钟
0 * * * * 每小时整点
30 8 * * * 每天 08:30
0 7,8 * * * 每天 07:00 和 08:00
*/15 * * * * 每 15 分钟
0 0 * * 0 每周日 00:00
0 6 1 * * 每月 1 号 06:00
0 9 * * 1-5 周一至周五 09:00

编辑与查看

# 编辑当前用户的 cron(自动用默认编辑器)
crontab -e
# 查看当前用户的 cron
crontab -l
# 删除所有任务
crontab -r
# 给 root 编辑(如果当前是普通用户)
sudo crontab -e -u root

一个完整条目(本机真实示例)

# 每天 07:00 跑贴吧签到,输出追加到日志
0 7 * * * TIEBA_QUIET=1 /usr/bin/python3 /root/scripts/tieba_sign.py >> /var/log/tieba_sign.log 2>&1
# 每天 08:00 跑监控报告
0 8 * * * /usr/bin/python3 /root/scripts/monitor_report.py >> /var/log/monitor_report.log 2>&1

拆开看这条0 7 * * *:

  • 前面已经说了:每天 07:00。
  • TIEBA_QUIET=1 —— 设置环境变量传给脚本(脚本里用 os.environ 读取)。
  • /usr/bin/python3 —— 用绝对路径可以避免 PATH 差异导致找不到解释器。
  • >> /var/log/tieba_sign.log 2>&1 —— 把 stdout 追加到日志,2>&1 把 stderr 也一起写进去。

注意 | cron 环境变量很少:它不会加载你 ~/.bashrc 里的 PATH 和别名。所以写 cron 时:命令用绝对路径(如 /usr/bin/python3 而非 python3),需要特定环境就用前缀变量或写个小 wrapper 脚本。

最容易踩的坑

坑 说明 解法
任务没跑 时间写错/命令路径不对/权限不足 crontab -l 核对;日志看有没有报错
PATH 找不到命令 cron 环境里没有你的 ~/.bashrc 用绝对路径,或在命令前 source /etc/profile
脚本没执行权限 文件没加 +x chmod +x 或写为 bash script.sh
环境变量缺失 crontab 里不支持 export 用一行 KEY=val 前缀,或写进脚本
输出看不到 没重定向 末尾加 >> /var/log/xxx.log 2>&1

验证与排错

# 1) 确认任务在
crontab -l
# 2) 确认 cron 服务在跑
systemctl status cron
# 3) 看日志
tail -f /var/log/tieba_sign.log
# 4) 手动跑一次,排查脚本本身问题
/usr/bin/python3 /root/scripts/tieba_sign.py

提示 | 不要用 crontab -r 清空;想停某个任务,注释那一行即可。改完 cron 无需重启,crond 每分钟自动重新读取。

延伸:systemd timer 替代方案

cron 简单可靠,但 systemd timer 更"体系化":可依赖、可记录、可查看上次运行时间。cron 够用就不折腾。详见《服务、定时任务与脚本 · Systemd 基础》。