我正在尝试使用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
上使用超时也不是一个可行的解决方案。
提前致谢
答案 0 :(得分:0)
好的,我找到了解决方案。
Python(即p.wait
)挂起的原因是因为rrdtool不知道最小步长(参数-S
)导致步长为2秒。这样,rrdtool的输出能够填充操作系统缓冲区和死锁p.wait
。根据Python文档,Popen.communicate
应该是一种方法。