返回列表 发布新帖
查看: 26|回复: 0

Cron 定时任务完全指南:从零配置到疑难杂症一网打尽

988

主题

0

回帖

833

积分

高级会员

积分
833
发表于 2026-6-25 02:55:01 | 查看全部 |阅读模式
最近帮几个同事排查 cron 定时任务的问题,踩了不少坑,顺手整理一下,希望能帮到同样在这里转圈的朋友。

先说配置语法,这是很多人第一关就搞错的地方。cron 表达式是五段:分 时 日 月 周,顺序别记混。我见过不止一个同事把"每天凌晨两点执行"写成 `2 * * * *`,结果变成每小时第二分钟跑一次,日志刷得飞起还百思不得其解。正确写法应该是 `0 2 * * *`。建议大家写之前先用 crontab.guru 这个网站验证一遍,省心省力。

环境变量是第二大坑,而且特别隐蔽。cron 运行时的环境和你 SSH 登录后的 shell 环境完全不一样,PATH 路径非常有限,很多命令直接找不到。你在终端里敲 `python3 backup.py` 没问题,但 cron 跑起来就报"command not found"。解决办法要么在脚本开头手动 export PATH,要么在 crontab 文件顶部加一行 `PATH=/usr/local/bin:/usr/bin:/bin`,要么直接用绝对路径调用命令,比如 `/usr/bin/python3 /home/user/backup.py`。我个人倾向于脚本里自己管理环境,这样移植性更好。

用户身份问题也经常被忽视。用 `crontab -e` 编辑的是当前用户的 crontab,而 `/etc/crontab` 或者 `/etc/cron.d/` 下面的文件则是系统级别的,可以指定运行用户。如果你的脚本需要写某个只有 root 才能操作的目录,普通用户的 crontab 跑起来肯定权限不够。排查时一定要先确认任务是以哪个用户身份在跑,`ps aux | grep cron` 或者看日志都能确认。

说到日志,这是排查问题最直接的手段,但很多人不知道 cron 默认就有日志。在 Ubuntu/Debian 系统上看 `/var/log/syslog`,在 CentOS/RHEL 上看 `/var/log/cron`,过滤一下 `grep CRON /var/log/syslog` 就能看到任务有没有被触发、触发时间对不对。更建议的做法是在 crontab 里把输出重定向到文件,比如 `0 2 * * * /path/to/script.sh >> /var/log/myscript.log 2>&1`,这样脚本里的错误信息也都留下来了,不然 stderr 默认会发邮件给用户,服务器上没配邮件的话就直接丢掉了,你根本不知道脚本报了什么错。

还有一个坑是脚本本身没有执行权限。脚本写完了,cron 配置也没问题,但就是不跑,检查一下 `ls -l /path/to/script.sh`,看看有没有 x 权限,没有的话 `chmod +x` 加上去。另外,脚本里如果用到了相对路径,也会出问题,因为 cron 执行时的工作目录默认是用户的 home 目录,不是脚本所在的目录。最保险的做法是脚本一开头就 `cd "$(dirname "$0")"` 切到脚本目录,或者全程使用绝对路径。

最后说一点系统时区的问题。如果你的服务器时区设置有问题,或者你在 Docker 容器里跑 cron,时区很可能是 UTC,而你写表达式时默认按北京时间算,就会差八个小时。检查方法很简单,`date` 命令看一眼当前系统时间,如果和预期不符就要先把时区对齐再配任务。

总结一句话:cron 的问题八九成不是 cron 本身的问题,而是环境、路径、权限、日志这些基础设施没搞清楚。养成写完任务就手动跑一遍脚本、看一眼日志的习惯,能省去大量调试时间。
回复 转播

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表