cron不加载shell配置导致命令找不到,需显式设PATH或用绝对路径;工作目录为根目录,须用cd切换;%等特殊字符需转义;应重定向日志并开启cron系统日志。

环境变量和 PATH 在 cron 中不生效
cron 启动时不会加载用户的 shell 配置(如 ~/.bashrc 或 /etc/profile),所以脚本里用到的命令(比如 python3、node、mysqldump)如果不在 /usr/bin 或 /bin 下,就会报 command not found。
解决方法:在 crontab 里显式设置 PATH,或用绝对路径调用命令:
PATH=/usr/local/bin:/usr/bin:/bin 0 2 * * * /usr/bin/python3 /home/user/backup.py
更稳妥的做法是,在脚本开头也手动补全环境,比如 Python 脚本里加:
import os
os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin' + os.environ.get('PATH', '')- 别依赖
which python3的输出来写 crontab —— 它在交互式 shell 里运行,和 cron 环境不一致 - 用
env > /tmp/cron_env.txt临时 dump 出 cron 的真实环境,对比排查
cron 日志没开或看不懂错误输出
默认 cron 不会把执行失败的 stderr 打印到屏幕,也不会自动记录完整错误堆栈,只可能在系统日志里留一行“failed”。
务必让任务把输出重定向出来:
0 3 * * * /path/to/script.sh >> /var/log/myscript.log 2>&1
同时确认 rsyslog 或 syslog-ng 已启用 cron 日志:
- 检查
/etc/rsyslog.conf是否有cron.* /var/log/cron这行(取消注释) - 重启服务:
sudo systemctl restart rsyslog - 然后用
sudo tail -f /var/log/cron实时观察调度行为
注意:有些发行版(如 Ubuntu 22.04+)默认禁用 cron 日志,需手动开启。
权限、路径、用户上下文不匹配
cron 以指定用户身份运行,但常被忽略的是:当前工作目录不是用户 home,也不是脚本所在目录,而是 / 根目录。所以脚本里所有相对路径(如 ./config.json、../data/)都会失败。
- 脚本开头强制切换工作目录:
cd /home/user/myproject || exit 1 - 用绝对路径读写文件,避免
open("log.txt")这类调用 - 确认目标用户对脚本、配置、输出目录都有读/写/执行权限(
chmod +x脚本,chown user:user /path/to/output) - 如果是
root用户的 crontab,而脚本里用了sudo,大概率卡住或失败 —— cron 不支持交互式密码输入
特殊字符未转义导致语法解析失败
crontab 行里 % 是特殊字符,会被解释为换行并把后面内容当 stdin。如果你的命令含 date +%Y%m%d 或 echo "a%b",整行就直接被截断,cron 甚至不会尝试执行。
修复方式:对每个 % 加反斜杠转义:
0 4 * * * /usr/bin/bash -c 'echo "backup_$(date +\%Y\%m\%d).tar.gz"' >> /tmp/backup.log
其他常见陷阱:
-
*和?在 shell 命令中要防止被 cron 提前展开(建议整个命令包在单引号里) - 脚本路径含空格?必须用引号包裹,但 crontab 对引号处理很脆弱,不如把路径软链到无空格位置
- 编辑 crontab 一定要用
crontab -e,不要直接改/var/spool/cron/*文件 —— 权限或格式错一点,整个用户 crontab 就失效
真正难定位的问题,往往不是脚本逻辑错,而是 cron 本身在静默地跳过某一行 —— 检查 sudo grep CRON /var/log/syslog 输出里有没有 “Syntax error” 或 “bad username” 这类提示,比反复试运行更高效。










