cron不加载用户配置文件导致shell变量不可用,因其使用非交互式最小化shell且path仅含/usr/bin:/bin;应通过env命令查看真实环境,统一使用绝对路径、在crontab顶部声明变量或用包装脚本加载环境。

定时任务里拿不到 Shell 变量,不是脚本写错了,是 cron 根本不加载你平时用的那些配置文件。它启动的是非交互式、非登录式的最小化 shell(通常是 /bin/sh),PATH 就两条路:/usr/bin:/bin,~/.bashrc、~/.profile、/etc/profile 全都不读——所以变量自然“消失”。
明确 cron 的真实环境
别猜,让它自己说出来:
- 在
crontab -e里加一行:* * * * * env > /tmp/cron_env.txt 2>&1 - 等一分钟,运行
cat /tmp/cron_env.txt,重点看PATH、HOME、SHELL、USER - 再对比
env或sudo -u youruser env,差异一目了然
所有命令必须用绝对路径
这是最稳、最直接的办法。cron 不认 python、node、java 这类简名,因为它们不在默认 PATH 里:
-
python3→ 改成/usr/bin/python3或/usr/local/bin/python3(用which python3确认) -
java→ 改成/usr/lib/jvm/java-11-openjdk-amd64/bin/java -
ifconfig、iptables在/sbin或/usr/sbin,也要写全路径
在 crontab 开头显式声明变量
在 crontab -e 文件最顶部(注释之后、任务之前)加环境变量行:
PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbinJAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64HOME=/home/youruser-
SHELL=/bin/bash(避免默认 sh 不支持某些语法)
这些设置对后续所有任务生效,比每行都写更干净。
用包装脚本统一加载环境
适合复杂场景(比如要用 conda、virtualenv 或大量自定义变量):
- 新建脚本
/home/user/run.sh,开头写:
#!/bin/bash<br>. /home/user/.bashrc<br>cd /home/user/project<br>/home/user/venv/bin/python main.py
- 给权限:
chmod +x /home/user/run.sh - crontab 里只调它:
0 2 * * * /home/user/run.sh >> /home/user/log.txt 2>&1
注意:用 .(点号)而不是 source,路径必须绝对,别写 ~。
不复杂但容易忽略:日志重定向一定要加,否则失败无声无息;脚本执行前确认有权限;PATH 宽一点总比窄安全。











