Crontab 是 Linux 上最经典的定时任务调度工具,从定时备份、日志清理、证书续签到定期同步数据,都可以用它实现全自动执行。本文讲清 crontab 的语法规则、编辑方法、日志记录、常见示例,以及容易踩坑的时区与环境变量问题。
本文要点
- crontab 时间字段语法速查(五字段含义)
- 用 crontab -e 编辑,用 -l 查看,用 -r 删除
- 输出重定向到日志文件,便于排查
- PATH 与环境变量陷阱
- 时区设置(系统时区 vs CRON_TZ)
crontab 时间语法
每条 crontab 任务由 5 个时间字段和命令组成:
# ┌───────────── 分钟(0–59)
# │ ┌─────────── 小时(0–23)
# │ │ ┌───────── 日(1–31)
# │ │ │ ┌─────── 月(1–12)
# │ │ │ │ ┌───── 星期(0–7,0 和 7 都是周日)
# │ │ │ │ │
* * * * * 要执行的命令| 特殊字符 | 含义 | 示例 |
|---|---|---|
| * | 任意值 | * 表示每分钟/每小时/每天 |
| , | 枚举 | 1,15 表示 1 日和 15 日 |
| - | 范围 | 1-5 表示周一到周五 |
| / | 步长 | */5 表示每 5 个单位 |
| @reboot | 开机执行 | @reboot 命令 |
常用时间表达式速查
| 表达式 | 含义 |
|---|---|
| 0 3 * * * | 每天凌晨 3 点 |
| */10 * * * * | 每 10 分钟一次 |
| 0 0 * * 0 | 每周日午夜 |
| 0 0 1 * * | 每月 1 日午夜 |
| 0 8-18 * * 1-5 | 工作日 8:00–18:00 每整点 |
| @reboot | 系统启动后执行一次 |
编辑与管理 crontab
# 编辑当前用户的 crontab(使用系统默认编辑器)
crontab -e
# 查看当前 crontab 内容
crontab -l
# 编辑指定用户的 crontab(root 操作)
crontab -u www-data -e
# 删除当前用户全部 crontab(危险!)
crontab -rcrontab -r 无确认提示
将输出重定向到日志
默认情况下 crontab 的输出会通过 sendmail 发送给用户,通常收不到。应将输出显式重定向到日志文件:
# 将标准输出和错误都写到日志
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# 带时间戳的日志写法
0 3 * * * echo "[$(date)] start" >> /var/log/myjob.log; /usr/local/bin/myjob.sh >> /var/log/myjob.log 2>&1
# 如果不想要任何输出(静默执行)
0 3 * * * /usr/local/bin/myjob.sh > /dev/null 2>&1PATH 与环境变量问题
crontab 运行时的 PATH 比交互式 Shell 短得多,很多命令找不到。有两种解决方法:
# 方法一:在 crontab 文件顶部设置 PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 方法二:在脚本或命令中使用绝对路径
0 3 * * * /usr/local/bin/rclone copy /backup r2:bucket/ >> /var/log/upload.log 2>&1时区设置
crontab 默认使用系统时区,搬瓦工 VPS 出厂通常为 UTC。先确认:
# 查看当前系统时区
timedatectl
# 修改系统时区为北京时间
timedatectl set-timezone Asia/Shanghai
# 或只为当前 crontab 指定时区(在 crontab 文件顶部)
CRON_TZ=Asia/Shanghai
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1时区与执行时间
实用示例
# 每天凌晨 3 点运行备份脚本
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# 每周日凌晨 4 点清理 7 天以上的日志文件
0 4 * * 0 find /var/log/myapp -name "*.log" -mtime +7 -delete
# 每 5 分钟检查一次服务是否在运行,不在则重启
*/5 * * * * systemctl is-active --quiet nginx || systemctl restart nginx
# 每月 1 日续签 SSL 证书(Let's Encrypt)
0 2 1 * * certbot renew --quiet >> /var/log/certbot.log 2>&1
# 系统启动后立即同步时间
@reboot ntpdate -u pool.ntp.org小结
- 五字段语法:分 时 日 月 周,* 代表任意,/ 代表步长
- crontab -e 编辑,-l 查看,备份后再 -r 删除
- 所有任务输出重定向到日志,方便排查执行情况
- 在 crontab 文件顶部设置 PATH 和 CRON_TZ 解决两大常见坑
- 用 systemctl 结合 crontab 实现简单的进程守护
常见问题
crontab 任务没有按时执行,怎么排查?
先用 systemctl status cron(或 crond)确认 cron 服务在运行;再检查日志 /var/log/syslog 或 /var/log/cron 里有无错误信息;确认命令使用绝对路径;手动执行脚本看是否报错。
crontab 和 systemd timer 该用哪个?
crontab 更简单直接,适合大多数定时脚本场景。systemd timer 功能更强(支持依赖、错误处理、journald 日志),适合对可靠性要求更高的生产任务。
如何让脚本在每次 reboot 后自动启动?
在 crontab 中加一行 @reboot /路径/脚本.sh 即可。如果需要更健壮的自启,推荐用 systemd service 配置 WantedBy=multi-user.target。
定时任务能操作数据库吗?
可以。脚本中直接用 mysql -u user -ppassword dbname -e 'SQL' 或 mysqldump 等命令即可。密码直接写在脚本里时注意文件权限,chmod 700 保证只有 owner 可读。