最近遇到的一个cron job的坑

最近写了一个Python程序,将其添加到了cronjob中,希望让其定期自动运行,但一直不能正常工作。其实在这之前一直在使用cronjob,也从没遇到过什么问题,因此感觉肯定是一个很初级的错误导致的。 下面把这次排错的经历记录一下。

image.png
图源:Pixabay

其crontab设置如下:

30 04 * * * /home/aafeng/batch/liker/aafeng_liker.sh >> /home/aafeng/cronjobs/logs/aafeng_liker.log

它就是不工作,而且日志文件为空,根本就没有任何线索可循。

首先想到的是环境变量的配置有问题。于是添加了这一句:

. $HOME/.bash_profile    

其作用就相当于运行:

source $HOME/.bash_profile  

这样就能保证在运行脚本之前装载所有环境变量,于是Cron job就成为了:

30 04 * * * . $HOME/.bash_profile; /home/aafeng/batch/liker/aafeng_liker.sh >> /home/aafeng/cronjobs/logs/aafeng_liker.log    

但仍然没有任何作用。

检查一下系统日志文件/var/log/syslog,发现这条错误信息:

Apr 20 11:11:02 vmi164206 CRON[16662]: (CRON) info (No MTA installed, discarding output)

这条错误消息说明,Cron job产生了输出,Cron守护进程想要将这些输出通过email发送给我,但是我的MTA (Mail Transfer Agent) 并没有配置,因此才出现上面的错误提示。

要想解决这个问题,有几种不同的方法:

  • 安装并配置MTA,比如:postfix,但我在VM上根本就不使用mail,因此并不想采取这种方式
  • 进行错误输出重定向,添加: 2>&1,将错误输出到日志文件中

我选择了第二种方式,这样Cron job就成为了:

30 04 * * * . $HOME/.bash_profile; /home/aafeng/batch/liker/aafeng_liker.sh >> /home/aafeng/cronjobs/logs/aafeng_liker.log 2>&1

再检查自己的日志文件,终于有输出了:

Traceback (most recent call last):
  File "likercli.py", line 3, in <module>
  import mysql.connector
  ModuleNotFoundError: No module named 'mysql'

提示找不到mysql这个库。但我明明已经安装了啊。 将Python的完整路径添加后问题解决:

/home/aafeng/environments/myenv/bin/python xxxxxx

其实这并不能完全解释为什么找不到mysql这个库。因为前面已经通过

 . $HOME/.bash_profile

装载了所有配置,包括Python virtual env,这样应该就能直接定位到/home/aafeng/environments/myenv/bin/python 啊,但就是无法直接工作。算了,既然加上完整的Python路径能正常运行,就先这么用吧了。