2017-07-04 3 views
0

Ich versuche Pythons Popen() zu verwenden, um Diagrammdaten aus mehreren Rrd-Dateien abzurufen. Aufgrund der Komplexität der Anwendung, wo das folgende Stück Code verwendet wird, verlasse ich mich auf rrdtool graph Parameter -Z für fehlende Dateien für mich Handhabung:Python 3 Popen Aufruf rrdtool hängt auf unbestimmte Zeit

#!/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")) 

folgenden Code wie erwartet funktioniert, wenn beide Dateien ch1.rrd und ch2. Rrd sind anwesend. Wenn einer von ihnen fehlt, bleibt die ganze Sache unbestimmt, bis ich den rrdtool-Prozess manuell von htop abbringe. Dann erkennt Python Rückgabecode ungleich Null und meldet Fehler.

Die Verwendung von shell=False und shlex.split() auf cmd hilft nicht.

Wenn ich den gleichen Befehl von Bash ausführen, erledigt Rrdtool auch mit den fehlenden Dateien den Job wie erwartet.

Leider kann ich nicht rrdtool Bindungen für Python verwenden und auch ich bin auf Python 3.4.5 stecken. rrdtool Version ist 1.6.0.

Ich bin gabl für jede Idee, wie Sie das zu überwinden. Ich würde eine Lösung vorziehen, die das Testen nicht einschließt, ob Dateien von Python existieren und den Parameter -Z im rrdtool Befehl behält. Auch die Verwendung von Timeout auf p.wait() ist keine praktikable Lösung.

Vielen Dank im Voraus

+0

Versuchen Sie STDERR auch in Ihrem 'subprocess.Popen()' Aufruf zu erfassen (d. H. 'Stderr = subprocess.PIPE') – zwer

Antwort

0

Ok, ich habe die Lösung gefunden.

Der Grund, warum Python (nämlich p.wait) gehängt war, weil rrdtool nicht die Mindestschrittgröße wußte (Parameter -S), die sich in Schrittgröße von zwei Sekunden. Auf diese Weise war die Ausgabe des rrdtool in der Lage, die OS-Puffer und die festgefahrenen p.wait zu füllen. Laut Python-Dokumentation sollte Popen.communicate ein Weg sein.

Verwandte Themen