Читать с терминала в Python

1

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

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

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

  • 0
    Если программа ожидает интерактивного ввода / вывода, попробуйте pexpect: noah.org/wiki/Pexpect . В противном случае использование subprocess.PIPE и вызов myprocess.communicate() должны работать.
Теги:
terminal

2 ответа

1

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

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

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

Если ни один из вышеперечисленных вариантов не работает для вас, вы сводились к решению проблем ввода/вывода concurrency.

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

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

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню