2017-07-04 16 views
0

我试图使用Python的Popen()从多RRD文件检索图形数据。由于其中使用了下面这段代码的应用程序的复杂性,我靠rrdtool的图形参数-Z处理丢失的文件对我来说:的Python 3 POPEN调用rrdtool的无限期挂起

#!/bin/python3 

import subprocess 

cmd = '/opt/rrdtool/bin/rrdtool graph - -a JSONTIME -Z --width 924 --start 1486428000 --end 1486471200 DEF:foo1=ch1.rrd:flows:MAX DEF:foo2=ch2.rrd:flows:MAX AREA:foo1#000:"ch1" AREA:foo2#606060:"ch2":STACK' 
path = '/data/live/pokus/rrd/channels/' 

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=path, shell=True) 
p.wait() 
if p.returncode is not 0: 
    print("Error") 
else: 
    print(p.stdout.read().decode(encoding="utf-8")) 

下面的代码工作当这两个文件ch1.rrd和CH2的预期。 rrd是存在的。当其中一个丢失时,整个事件将无限期挂起,直到我从htop手动杀死rrdtool进程。然后python检测到非零返回码并报告错误。

使用shell=Falseshlex.split()cmd没有帮助。

当我执行从bash中相同的命令,即使丢失的文件rrdtool的做工作按预期。

不幸的是我不能使用rrdtool的绑定Python和也我被困在蟒蛇3.4.5。 rrdtool版本是1.6.0。

我GLAB任何想法如何克服这一点。我更喜欢这个解决方案,它不包括测试python中是否存在文件,并在rrdtool命令中保留-Z参数。在p.wait()上使用超时也不是一个可行的解决方案。

在此先感谢

+0

尝试捕获STDERR您'subprocess.Popen()'调用以及(即'标准错误= subprocess.PIPE') – zwer

回答

0

好吧,我找到了解决方案。

Python(即p.wait)被吊死的原因是rrdtool不知道导致步长为2秒的最小步长(参数-S)。这样,rrdtool的输出能够填补OS缓冲器和僵持p.wait。根据Python文档,Popen.communicate应该是一种方法。