Стандартният изход на подпроцес на Python не чете

Опитвам се да стартирам gnuplot чрез python.

Мога да изпращам и изпълнявам команди, но не мога да чета предупрежденията или съобщенията за грешка от приложението. Той просто чака тук: "self.proc.stdout.readline()".

Ето целия ми код:

from subprocess import PIPE, Popen

import fcntl, os

class Gnuplot:
    def __init__(self, debug=True):
        self.debug = debug
        if self.debug:
            print 'Initializing ...\n' 

        self.proc = Popen(['gnuplot','-persist'],stdin=PIPE, stdout=PIPE, stderr=PIPE)  
        fcntl.fcntl(self.proc.stderr.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

    def communicate(self, cin='\n'):
        self.proc.stdin.write(cin+'\n')
        cout, cerr = '', ''
        print "lol"
        if self.proc.stdout:
            cout = self.proc.stdout.readline()
            self.proc.stdout.close()
            print cout
        elif self.proc.stderr:
            cerr = self.proc.stderr.read()
            self.proc.stderr.close()
            print cerr


if __name__ == '__main__':
    g = Gnuplot()   
    g.communicate("set parameter\n")
    g.communicate("plot sin(x)\n")     

Просто чака тук:

cout = self.proc.stdout.readline()

person user3817833    schedule 22.11.2014    source източник


Отговори (1)


Предупрежденията и грешките обикновено се извеждат в стандартния поток от грешки, а не в стандартния изход (това спира резултатите да се смесват с предупредителните съобщения, например). Тъй като първо четете от stdout и не се дава резултат, не стигате до частта, в която четете от stderr.

Имайте предвид, че subprocess не препоръчва директен достъп до потоците:

Предупреждение: Използвайте communicate() вместо .stdin.write, .stdout.read или .stderr.read, за да избегнете задънени блокировки, дължащи се на запълване и блокиране на дъщерния процес на който и да е от другите буфери на канала на ОС.

Вероятно искате да използвате process.communicate(), както е предложено. Това ви дава кортеж от stdout_data, stderr_data, така че просто вземете втория, за да получите своите предупреждения и грешки. Това избягва проблема с необходимостта от ръчно четене на изхода и проблеми като този.

person Gareth Latty    schedule 22.11.2014