记一次使用Crontab的错误排查
我们常常会有一些定时任务处理的需求,Linux上大多使用Crontab来实现。
趁机记录下最近新开的一台机上使用Crontab的错误排查。
系统是Ubuntu20.04
前置需求
每天定时运行一次虚拟环境下的Python脚本并留存运行日志保存起来。
最初实现
根据需求,很容易写出下面的规则。
1 | crontab -e |
start.sh
内容如下
1 | source venv/bin/activate |
信誓旦旦的等待中,到点后却发现run.log
一直都是空的,出现问题了。
错误排查
首先检查命令。
1
~/XXX/start.sh >> ~/XXX/run.log 2>&1
没问题,正常输出追加log。
查看Crontab状态和执行日志。
1
2
3
4
5
6# 查看Crontab状态
service cron status
...
# 查看Crontab执行日志
grep cron /var/log/syslog
...发现时间和本地时间不同,并没有执行命令,方便调试,这里我们调成和本地一样的东八区。
1
2
3
4timedatectl set-timezone Asia/Shanghai
# 重启系统日志和Crontab使其修改生效
systemctl restart rsyslog
service crond restart时区正确后查看执行日志发现找不到
source
命令,且找不到venv/bin/activate
。Crontab所用的
/bin/sh
不包含source
命令,用.
代替运行脚本即可。找不到
venv/bin/activate
,是因为Crontab执行默认是在用户的根目录下,需要提前手动cd,在start.sh
中添加cd ~/XXX/
导出的log中文自动转码
Crontab执行的环境变量和用户不同导致的,在
start.sh
最顶部中添加export LANG=zh_CN.UTF-8
导入即可。
修正后的start.sh
1 | export LANG=zh_CN.UTF-8 |
总结
Crontab执行环境和用户执行环境差的有点多,很零碎的参考,记得快忘的也快。
记一次使用Crontab的错误排查