Python Запустить подпроцесс демона и прочитать stdout

Мне нужно запустить программу и собрать ее вывод в stdout. Эта программа (socat) должна работать в фоновом режиме на протяжении всего сценария python. Socat сидит в режиме dameon после его запуска, но сначала он выводит некоторые строки в stdout, которые мне нужны для остальной части моего скрипта.

Команда: socat -d -d PTY: PTY:

Вывод:

 2011/03/23 21:12:35 socat[7476] N PTY is /dev/pts/1 2011/03/23 21:12:35 socat[7476] N PTY is /dev/pts/2 2011/03/23 21:12:35 socat[7476] N starting data transfer loop with FDs [3,3] and [5,5] 

Я в основном хочу запустить это в начале моей программы и оставить его запущенным до завершения скрипта, но мне нужно прочитать два / dev / pts / X names в python.

Может ли кто-нибудь сказать мне, как это сделать?

Я придумал это, которое просто зависает, я думаю, потому что это блокирование для завершения дочернего процесса.

 #!/usr/bin/python from subprocess import Popen, PIPE, STDOUT cmd = 'socat -d -d PTY: PTY: &' p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) output = p.stdout.read() # Process the output print(output) 

Спасибо за любую помощь

EDIT: Кажется, он может писать в stderr, но сценарий все еще просто меняется с и без чтения и даже чтения из stderr.

 #!/usr/bin/python from subprocess import Popen, PIPE, STDOUT import pty import os cmd = 'socat -d -d PTY: PTY:' master, slave = pty.openpty() p = Popen(cmd, shell=True, stdin=PIPE, stdout=slave, stderr=slave, close_fds=True) stdout = os.fdopen(master) print stdout.readline() print stdout.readline() 

Есть две проблемы с вашей версией. Во-первых, вы называете чтение без аргумента, что означает, что он попытается прочитать все. Но так как сокат не заканчивается, он никогда не решает, что он все прочитал. Используя readline, python читает только до тех пор, пока не найдет новую строку. Из моего понимания вашей проблемы это то, что вам нужно.

Вторая проблема заключается в том, что стандартная библиотека C будет буферизовать выходы на трубах. Мы решаем это, создавая pty с функцией openpty () и передавая его как stdout, так и stderr подпроцесса. Мы используем fdopen, чтобы сделать этот дескриптор файла регулярным объектом python, и мы избавляемся от буферизации.

Я не знаю, что вы делаете с socat, но мне интересно, можно ли заменить его с помощью модуля pty. Вы копируете один pty в другой, а openpty создает пару pty. Возможно, вы можете использовать их напрямую?

Подпроцесс, вероятно, никогда не закрывает stdout, поэтому вызов read() ожидает навсегда. Чтобы усугубить ситуацию, он, вероятно, будет буферизовать свой результат, когда выяснит, что это канал вместо консоли (стандартная библиотека C делает это автоматически, так что это не функция того, насколько умно написано приложение). Если это так, вероятно, единственный вариант – использовать библиотеку ожидающего стиля, такую ​​как Pexpect .

Если вы снабдите его трубкой для stdout и stderr, я думаю, что подпроцесс заблокирует ожидание чтения каналов. .read () должен читать EOF, я думаю. Между ними эти два вопроса прорываются в тупик.

Однако, я думаю, что, поскольку .read () будет читать до EOF, он будет блокироваться, даже если нет трубы stderr.

Думаю, вы хотите придерживаться чтения в потоке.