Python 3 Popen调用rrdtool无限期挂起

时间:2017-07-04 13:11:05

标签: subprocess python-3.4 rrdtool

我正在尝试使用Python的Popen()从多个rrd文件中检索图形数据。由于应用程序的复杂性,使用下面的代码,我依靠rrdtool图形参数-Z来处理丢失的文件:

#!/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=False上使用shlex.split()cmd无效。

当我从bash执行相同的命令时,即使丢失了文件,rrdtool也会按预期执行该作业。

不幸的是我不能为rthon使用rrdtool绑定,而且我仍然坚持使用python 3.4.5。 rrdtool版本为1.6.0。

我想知道如何克服这个问题。我更喜欢不包括测试文件是否存在于python并且在-{1}}命令中保留-Z参数的解决方案。在rrdtool上使用超时也不是一个可行的解决方案。

提前致谢

1 个答案:

答案 0 :(得分:0)

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

Python(即p.wait)挂起的原因是因为rrdtool不知道最小步长(参数-S)导致步长为2秒。这样,rrdtool的输出能够填充操作系统缓冲区和死锁p.wait。根据Python文档,Popen.communicate应该是一种方法。