Читать с терминала в Python - PullRequest
1 голос
/ 15 июня 2011

Как я могу получить ввод с терминала в Python?

Я использую Python для взаимодействия с другой программой, которая генерирует выходные данные из пользовательского ввода. Я использую subprocess.Popen () для ввода в программу, но я не могу установить для stdout значение subprocess.PIPE, потому что программа, похоже, никогда не сбрасывается, поэтому все застревает в буфере. Стандартным выводом программы является вывод на терминал, и я вижу вывод, когда не перенаправляю стандартный вывод. Однако мне нужен Python для чтения и интерпретации вывода, который сейчас находится в терминале.

Извините, если это глупый вопрос, но я не могу заставить его работать.

Ответы [ 2 ]

1 голос
/ 15 июня 2011

Буферизация в дочерних процессах является распространенной проблемой. Вот четыре возможных подхода.

Во-первых, проще всего, вы можете читать по одному байту за раз из вашего канала. Это то, что я бы назвал «грязным хаком», и он несет в себе снижение производительности, но это легко, и он гарантирует, что ваши вызовы read () будут блокироваться только до появления первого байта, а не ждать, пока буфер заполнится. никогда не заполнится. Однако это не заставляет другой процесс очищать свой буфер записи, поэтому, если это проблема, этот подход вам все равно не поможет.

Во-вторых, и я думаю, что в следующем, простейшем случае, рассмотрите возможность использования Twisted Framework, в котором есть средство для использования виртуального терминала, или pty (я думаю, «псевдо-телетайп») для общения с вашим дочерним процессом. Тем не менее, это может повлиять на дизайн вашего приложения (возможно, в лучшую сторону, но это может не быть в карточках для вас независимо от). http://twistedmatrix.com/documents/current/core/howto/process.html

Если ни один из вышеперечисленных вариантов не подходит для вас, вы сами решаете сложные проблемы параллелизма ввода-вывода.

В-третьих, попробуйте установить ваши каналы (все они, перед fork ()) в неблокирующий режим, используя fcntl () с O_NONBLOCK. Затем вы можете использовать select () для проверки готовности к чтению / записи, прежде чем пытаться читать / писать; но вы все равно должны поймать IOError и проверить EAGAIN, потому что это может произойти даже в этом случае. Это может, в зависимости от поведения дочернего процесса, позволить вам подождать, пока данные действительно появятся, прежде чем пытаться их прочитать.

Последнее средство - реализовать логику PTY самостоятельно. Если вы видели ссылки на такие вещи, как опции termio, вызовы ioctl () и т. Д., То вы против этого. Я не делал этого раньше, потому что это сложно, и я никогда не нуждался в этом. Если это твоя судьба, удачи.

0 голосов
/ 15 июня 2011

Вы пытались установить bufsize в вашем Popen объекте на 0?Я не уверен, что вы можете заставить буфер быть небуферизованным из полученного размера, но я бы попробовал.

http://docs.python.org/library/subprocess.html#using-the-subprocess-module

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...