手动跑得好好的脚本,一进 crontab 就报错:cron 的环境和你登录 shell 的环境不是一回事

举报
yd_219824599 发表于 2026/11/11 20:16:21 2026/11/11
【摘要】 SSH 上手动执行备份脚本一切正常,进了 crontab 就报 python3: command not found。原因是 cron 不读 profile,只有 PATH=/usr/bin:/bin。文中给出十秒定位环境的命令、三种改法的优先级,以及错误输出被丢弃这个最容易被忽略的坑。

现象

周六凌晨三点,备份脚本没有产出文件。SSH 上去手动执行 /opt/scripts/backup.sh,一秒跑完,日志里一切正常;crontab -l 里那行也没写错。于是整个周末都在怀疑磁盘满、权限、Python 依赖——其实都不是。

失败的那行日志只留下这么一句:

/opt/scripts/backup.sh: line 12: python3: command not found

python3 明明装在 /usr/local/bin/python3(自己编译装的),手动跑能找到,cron 跑就找不到。这就是最典型的判断依据:cron 用的是 PATH=/usr/bin:/bin 这个极简环境,它不读 /etc/profile、不读 ~/.bash_profile、不读 ~/.bashrc。你在 shell 里 echo $PATH 看到的那一长串,全是你登录时由 profile 脚本拼出来的,cron 完全看不到。

顺带说,这也是 cron 任务里 LANG、HOME、PYTHONPATH 缺失,中文文件名变成一串问号,以及 docker、nvm、conda 命令找不到的共同原因。

定位方法

不要猜,直接把 cron 的环境和自己的环境各打一份出来对比:

* * * * * env > /tmp/cron-env.txt 2>&1

env | sort > /tmp/login-env.txt
sort /tmp/cron-env.txt > /tmp/cron-env.sorted.txt
diff /tmp/cron-env.sorted.txt /tmp/login-env.txt | head -30

PATH、HOME、SHELL、LANG 这几行的差异,基本就能对上你遇到的每一个报错。

三种改法,按推荐顺序

1. 在脚本里自己声明环境(最稳,脚本还能单独手动跑)

#!/bin/bash
export PATH=/usr/local/bin:/usr/bin:/bin
export LANG=zh_CN.UTF-8
export PYTHONPATH=/opt/scripts/lib
cd /opt/scripts || exit 1
exec /usr/local/bin/python3 backup.py >> /var/log/backup.log 2>&1

关键点:脚本开头 cd 到绝对路径。cron 的工作目录是执行用户的家目录,脚本里任何相对路径(配置文件、日志、./data)在 cron 下都会指错地方,这也是「手动跑正常、cron 跑报找不到文件」的另一个高频原因。

2. 在 crontab 顶部统一声明(适合一个用户下很多任务)

PATH=/usr/local/bin:/usr/bin:/bin
LANG=zh_CN.UTF-8
SHELL=/bin/bash
MAILTO=""

30 3 * * * /opt/scripts/backup.sh

注意 crontab 里的变量赋值不支持 shell 语法:PATH=$PATH:/opt/bin 这种写法在这里无效,会原样当成一个名为 PATH 的字面值。

3. 直接写绝对路径(改动最小)

30 3 * * * /usr/local/bin/python3 /opt/scripts/backup.py

这种做法能解决「命令找不到」,但解决不了 PYTHONPATH、LANG 和相对路径的问题,适合只有单个脚本的简单场景。

一个容易漏掉的坑

把 2>&1 只写在命令末尾,邮件却没配、MAILTO 也没设,错误输出会被直接丢弃——于是你看到的就是「任务没跑,日志里什么都没有」。调试阶段先在命令后加 >> /tmp/cron-run.log 2>&1,确认稳定后再去掉。

另外,systemd 服务同理:它的环境既不来自登录 shell,也不来自 crontab,而是来自 unit 文件里的 Environment= 或 EnvironmentFile=,排查思路一致,只是要换地方改。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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