crontab中,sh.ifconfig()
执行不不了,报错类似如下
Traceback (most recent call last):
File "/home/pi/system/sensor_ip.py", line 7, in <module>
LineaX = sh.grep(sh.ifconfig('eth0'), '-oP', '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
File "/usr/local/lib/python2.7/dist-packages/sh.py", line 2301, in __getattr__
return self.__env[name]
File "/usr/local/lib/python2.7/dist-packages/sh.py", line 2232, in __getitem__
return Command._create(k, **self.baked_args)
File "/usr/local/lib/python2.7/dist-packages/sh.py", line 776, in _create
raise CommandNotFound(program)
sh.CommandNotFound: ifconfig
网上找,很多说是PATH
的事情,第一反应是按照sys.path
去找,比如这个crontab中运行python程序出错,提示ImportError: No module named解决全过程, 结果比较了一下,发现一样!所以不是python版本的事
, import sh
也可以一直执行。浪费了一晚上到三点找不到方法,没戏就睡了!
今天决定跟着源码去定位,终于找到这家伙了。
/usr/local/lib/python2.7/dist-packages/sh.py
def which(program):
def is_exe(fpath):
return (os.path.exists(fpath) and
os.access(fpath, os.X_OK) and
os.path.isfile(os.path.realpath(fpath)))
fpath, fname = os.path.split(program)
#lucifer
#print 'fpath={0},fname={1}'.format(fpath,fname)
if fpath:
if is_exe(program):
return program
else:
if "PATH" not in os.environ:
return None
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
return None
上面说的是,比如你执行sh.ifconfig()
,就需要知道ifconfig
的位置,从os.environ[`PATH`]
中去找,找不到就甩出来这个异常。
所以只要在自己的脚本中加上下面这句话就OK了
#Crontab PATH is not same compared with user.path
#This is for sh.commands
if '/sbin' not in os.environ['PATH']:
os.environ['PATH'] += ':/sbin'
先说说怎么测试是不是这个问题呢:
bash : which ifconfig
/sbin/ifconfig
#test.py
import sh
import os
print os.environ['PATH']
print sh.ifconfig()
两个直接执行,一个用crontab
后台执行并输出,比较下就可以看到了。
源码调试中,可以发现在crontab
下找不到ifconfig
位置,但是不用crontab
就可以。就可以确定是这个问题引起的。
果然,源码大法好!!!
之所以提这个,是因为很多人说是python lib path
的事情,测试后发现不是,sh
包可以找到,但sh
本身执行也需要PATH
,一些第三方package
偶尔会出这个问题。