crontab 定时任务不执行:先查环境变量、路径和日志,再怀疑时间写错了

举报
yd_274356910 发表于 2026/11/05 09:25:38 2026/11/05
【摘要】 定时任务到了时间却没跑,先别急着改时间表达式:按服务与任务存在性、日志、环境变量与路径、手动复现、权限与输出重定向的顺序排查,多数问题出在环境差异上。

定时任务写好了,到了时间却没有跑,是运维里很常见的一类问题。很多人第一反应是去改时间表达式,或者怀疑服务器时间不对。其实更常见的根因在另外三处:环境变量、路径和日志。按下面这个顺序查,往往十分钟就能定位。

第一步:先确认任务到底有没有被调度

先看两点。第一,cron 服务是不是在跑:

systemctl status cron
systemctl status crond

不同发行版服务名不一样,cron 和 crond 试一个能命中的就可以。第二,看任务是不是真的写进了当前用户的 crontab,而不是只写在了一个普通文本文件里:

crontab -l

如果 crontab -l 里根本没有这条任务,后面的排查都没有意义。系统级任务还要看 /etc/crontab 和 /etc/cron.d/ 下的文件,系统级 crontab 的时间后面多了一个执行用户字段,格式和用户级不一样,照抄用户级写法容易写错。

第二步:看日志,确认任务有没有被触发

cron 有没有触发,和脚本有没有跑成功,是两回事。先区分这一点,能省掉一半弯路。

# Debian / Ubuntu 系列
 grep CRON /var/log/syslog
# RHEL / CentOS 系列
 tail -n 100 /var/log/cron
# 有 systemd 的机器也可以这样看
 journalctl -u cron --since "1 hour ago"
 journalctl -u crond --since "1 hour ago"

日志里能看到任务被触发,说明调度本身没问题,问题在脚本或命令;日志里完全没有这条任务的记录,才需要回头查时间表达式、服务状态和权限限制,比如 /etc/cron.allow 和 /etc/cron.deny 有没有把当前用户挡在外面。

第三步:环境变量不一样,是最常见的坑

交互式登录 shell 和 cron 执行环境差别很大。登录后自动加载的 profile、bashrc 里的变量,cron 一概不加载;cron 默认的 PATH 也很短,一般只有 /usr/bin:/bin 这一类。于是出现一种典型现象:手动执行好好的,定时跑就报 command not found。

排查办法有两个。第一,把命令和脚本里的调用全部改成绝对路径,比如用 /usr/local/bin/python3 而不是 python3,用 /home/app/backup.sh 而不是相对路径。第二,在 crontab 顶部显式声明需要的变量,例如:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/home/app

依赖数据库密码、接口密钥这类变量的任务,不要只在交互 shell 里 export 一次就以为万事大吉,cron 读不到,任务会在半夜静默失败。

第四步:用 cron 的环境手动复现一次

这是最有说服力的一步:用一个极简环境手动跑一次任务,和 cron 的行为基本一致:

env -i HOME="$HOME" PATH="/usr/bin:/bin" SHELL="/bin/sh" LOGNAME="$(whoami)" /bin/sh -c '/home/app/backup.sh'

如果这样跑失败了,基本可以确定是环境差异;如果这样跑成功了,再回头查时间、时区和日志。服务器时区也值得看一眼:date 看到的时间、crontab 按哪个时区解释、业务上期望的是哪个时区,三者不一致时,任务会在“错误的时间准时执行”。

第五步:权限和输出重定向

脚本本身要有可执行权限,shebang 第一行要写对解释器,脚本里引用的目录要对执行用户可写。还有一个容易忽略的点:cron 任务的输出如果没有重定向,默认会以邮件形式发给任务属主,邮件服务没配时,这些输出就悄悄丢了。建议每条重要任务都显式重定向:

0 2 * * * /home/app/backup.sh >> /var/log/app/backup.log 2>&1

这样不管成功失败,都有地方可查。日志文件本身也要做轮转,否则几个月后又会因为日志把磁盘写满,回到另一类故障。

一个可复用的排查清单

  1. systemctl 确认 cron 服务在跑,crontab -l 确认任务确实存在。
  2. 查日志区分“没触发”还是“触发了但跑失败”。
  3. 检查 PATH、环境变量和绝对路径,手动用 env -i 复现一次。
  4. 检查脚本权限、shebang、执行用户和 cron.allow / cron.deny。
  5. 核对时区和时间表达式,给任务加上输出重定向。

按这个顺序走,大多数“定时任务不执行”都不需要改时间表达式。先把环境、路径和日志这三处查清楚,剩下的才是时间本身的问题。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。