crontab -e 编辑后不生效需检查三处:用户与系统crond服务匹配、crond服务是否运行、脚本中命令是否使用绝对路径;还需注意环境变量加载、日志重定向、高频任务处理及锁机制。

crontab -e 编辑后不生效?检查这三处
Linux 下用 crontab -e 添加定时任务后没运行,大概率不是语法写错,而是环境、权限或路径问题。
- 用户 crontab 和系统 crond 服务必须匹配:普通用户用
crontab -e,root 用sudo crontab -e;二者配置不互通 - crond 服务必须运行:
systemctl status cron(Debian/Ubuntu)或systemctl status crond(RHEL/CentOS),未激活则systemctl start cron - 脚本中所有命令必须用绝对路径:
/usr/bin/python3而非python3,/home/user/script.sh而非./script.sh;crond 默认$PATH极简(通常只有/usr/bin:/bin)
如何让 cron 正确加载当前 shell 环境变量?
cron 不读取 ~/.bashrc 或 /etc/profile,所以你在终端能跑通的命令,在 cron 里常因缺 $HOME、$PYTHONPATH 或自定义 alias 失败。
- 最稳妥方式:在脚本开头显式 source 环境文件,例如:
#!/bin/bash source /home/user/.bashrc export PATH="/home/user/.local/bin:$PATH" python3 /home/user/job.py
- 避免在 crontab 行内直接写
source:cron 解析器不支持该语法,会报bad command - 临时调试可加日志:
* * * * * /home/user/test.sh >> /tmp/cron.log 2>&1,然后tail -f /tmp/cron.log查看实际执行时的环境输出
分钟级高频任务(如每 10 秒跑一次)不能只靠 * * * * *
* 最小粒度是 1 分钟,无法实现秒级调度。硬凑 * * * * * sleep 10; cmd 会导致每次启动时间漂移,且并发风险高。
- 真需要 sub-minute 频率,改用后台循环 +
sleep:#!/bin/bash while true; do /home/user/check.sh sleep 10 done
,再用nohup ./loop.sh &启动,并配合 systemd service 管理生命周期 - 若仍想走 cron,可用多个错开的条目模拟(如
*/10 * * * * cmd+*/10 * * * * sleep 10; cmd),但不可靠,仅限临时验证 - 注意系统负载:高频任务务必在脚本内加锁(如用
flock),否则可能多个实例同时写同一文件或重复发请求
日志和错误捕获必须显式重定向,别信默认行为
cron 默认把 stdout/stderr 发邮件给用户(需本地 MTA 配置),多数服务器根本没配 sendmail,结果就是“静默失败”。
- 每行 cron 必须带重定向:
0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1 - 不要只写
2>&1:它只重定向 stderr 到当前 stdout,而 stdout 默认是空设备;必须先指定 stdout 输出位置,2>&1才有意义 - 日志轮转建议用
logrotate配合,或脚本内判断文件大小后mv backup.log backup.log.$(date +%s)
cron 的可靠性不取决于你写得多漂亮,而在于你是否提前堵住了环境差异、路径歧义和输出黑洞这几个口子。真正上线前,至少手动跑一遍脚本、查一遍 journalctl -u cron -n 50、翻一遍目标日志文件的权限和内容。










