Стандартный подпроцесс 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()
1 ответ
Предупреждения и ошибки обычно выводятся в стандартном потоке ошибок, а не в стандартном выводе (например, это останавливает смешивание результатов с предупреждающими сообщениями). Потому что вы читаете из stdout
во-первых, и не выводится, вы не попадаете в ту часть, где вы читаете stderr
,
Обратите внимание, что subprocess
не рекомендует обращаться к потокам напрямую:
Предупреждение. Используйте функцию connect (), а не.stdin.write,.stdout.read или.stderr.read, чтобы избежать взаимных блокировок из-за того, что другие буферы конвейера ОС заполняют и блокируют дочерний процесс.
Вы, вероятно, хотите использовать process.communicate()
как предложено. Это дает вам кортеж stdout_data, stderr_data
, так что просто возьмите второй, чтобы получить ваши предупреждения и ошибки. Это обходит проблему необходимости вручную читать вывод и подобные проблемы.