前言
最近在服务器Centos7上用crontab定时执行Python程序的时候遇到一个问题,python程序的log日志没有正常输出,最后发现原来跟crontab的执行路径有关。
问题描述
我的python程序是用logging
这个包进行log日志输出,通过os.getcwd()
来找到当前程序的目录,然后把log日志输出到当前目录的路径下。
python程序在linxu环境,通过python3 my_program.py
的方式执行,是正常运行,log日志都正常输出。但唯独通过crontab进行定时任务调度时候,日志就不输出了。
0 8 * * * * python3 /opt/module/my_program.py > /dev/null 2>&1 &
像这样设定每天早上8点执行我的python程序,但日志就是不输出。
原因核查
一开始以为有没有可能是logging
这个模块,假如设定了 > /dev/null
的方式,就不会输出日志。但马上我就否定了这个猜想。因为我尝试用这个语句手动执行,日志是正常输出的:
nohup python3 /opt/module/my_program.py > /dev/null 2>&1 &
所以原因还是出在了crontab的任务调度上。
首先可以肯定的是crontab执行的python程序是有运行的,因为我通过
ps -ef | grep python3
查看crontab调度的任务,程序是正常运行,但是就是找不到日志。那么只能认为日志输出到了别的地方去,那到底日志输出到哪了呢?问题来到了crontab执行的python程序中,os.getcwd()
获取的路径是否有问题。
于是我写了一个简单的测试代码:
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import os
file = open("/opt/module/example.txt", "a")
file.write(os.getcwd())
file.write("\n")
file.close()
然后用crontab去执行这个Python程序。结果发现,输出的路径竟然是/home/Patrick
,也就是我当前linux用户的家目录。
最后我进入/home/Patrick
这个目录下,果然找到了我的log日志。
那么原因已经显而易见了,就是crontab 默认执行路径是 /home/user_name目录下。
解决方案
网上有一个解决办法,说是写一个test.sh,把这个sh脚本放到程序的根目录下,通过crontab调度sh脚本来执行我的python程序。
但这个方法,我尝试了一次,效果跟原来没有变化,log还是输出到了家目录下。也许是我方法不对?
我的解决方案是:
crontab执行任务之前,先cd到目标目录下,再执行python程序。具体代码如下:
0 8 * * * * cd /opt/module; python3 ./my_program.py
crontab是可以通过;
实现执行多个命令。
这样就能保证crontab的定时任务,在自己需要的目录路径下执行了。