crontab -e 编辑后不生效需检查三件事:PATH环境变量未显式声明、命令未用绝对路径、目标用户无cron执行权限;日志需重定向并加时间戳;中文支持需设置LANG和LC_ALL环境变量。

crontab -e 编辑后不生效?检查这三件事
多数人写完定时任务发现没执行,不是语法错,而是环境或权限问题。Linux 的 cron 服务默认以系统用户身份运行,不会加载你的 shell 配置(比如 ~/.bashrc),所以脚本里用的命令如果依赖 $PATH 或自定义函数,大概率失败。
- 在脚本开头显式声明
PATH,例如:PATH=/usr/local/bin:/usr/bin:/bin - 所有命令用绝对路径,比如把
python改成/usr/bin/python3,把mysqldump改成/usr/bin/mysqldump - 确认目标用户有执行权限:如果用
sudo crontab -e,任务以 root 运行;如果直接crontab -e,是以当前用户身份运行,但该用户必须被允许使用 cron(检查/etc/cron.allow或确保不在/etc/cron.deny中)
Shell 脚本里怎么记录日志才方便排查?
定时任务静默执行,不加日志等于黑盒。别只靠 echo 打印,得把标准输出和标准错误都重定向到文件,并带上时间戳。
- 在 crontab 条目末尾加上
> /path/to/log.log 2>&1,例如:0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1 - 在脚本内部用
date +'%Y-%m-%d %H:%M:%S'打点日志,比如:echo "$(date +'%Y-%m-%d %H:%M:%S') - Starting backup" >> /var/log/backup.log - 避免日志无限增长:用
logrotate管理,或脚本开头加tail -n 1000 /var/log/backup.log > /var/log/backup.log.tmp && mv /var/log/backup.log.tmp /var/log/backup.log
如何让脚本在 crontab 里正确处理中文、UTF-8 和特殊字符?
crond 默认 locale 是 C,不支持中文路径、文件名或 echo 中文内容,会导致乱码甚至命令失败。
- 在 crontab 文件顶部加两行环境变量:
SHELL=/bin/bash和LANG=en_US.UTF-8(或你系统实际支持的 UTF-8 locale,可用locale -a | grep utf8查) - 脚本第一行加
#!/bin/bash,并在开头设置:export LANG=en_US.UTF-8、export LC_ALL=en_US.UTF-8 - 涉及文件名含中文时,避免用
ls *.txt这类 glob,改用find . -maxdepth 1 -name "*.txt" -print0 | while IFS= read -r -d '' file; do ... done,防止空格和 Unicode 截断
测试 crontab 条目是否真能跑通?别等凌晨两点
写完不能只等下次触发——crontab 不会校验命令是否存在或可执行,也不会提示语法外的逻辑错误。
- 先手动执行一遍:复制 crontab 行里的命令部分,在终端里粘贴运行(注意替换
%字符,它在 cron 里是特殊符号,需写成\%,但在 shell 直接执行时不需要) - 临时改成高频触发测试,比如
* * * * *(每分钟一次),确认日志有输出、无报错后再改回原周期 - 用
grep CRON /var/log/syslog(Ubuntu/Debian)或grep CRON /var/log/cron(CentOS/RHEL)看 cron 是否真正调用了你的任务,有没有 “Permission denied” 或 “Command not found”
真正难的不是写对 cron 时间格式,而是让脚本脱离交互式 shell 环境后依然可靠——PATH、locale、重定向、权限、字符编码,漏掉任意一个,它就在某天凌晨安静地失败。


















