Как мне взаимодействовать с консольным приложением, как будто я пользователь набираю в него что-то?

Я пытаюсь написать программу Python, которая взаимодействует с программой bsdgames trek. Это похоже на Zork с клингонами:

* * * STARTREK * * * Press return to continue. What length game: short What skill game: fair Enter a password: hunter2 10 Klingons 2 starbases at 3,6, 0,2 It takes 400 units to kill a Klingon Command: 

В настоящее время я пытаюсь использовать subprocess.Popen() для взаимодействия с ним:

 >>> import subprocess >>> t = subprocess.Popen('trek', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

К сожалению:

 >>> t.communicate('') ('', None) >>> t.poll() -2 >>> t.communicate('') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/subprocess.py", line 754, in communicate return self._communicate(input) File "/usr/lib/python2.7/subprocess.py", line 1297, in _communicate self.stdin.flush() ValueError: I/O operation on closed file 

Он заканчивается сам, как только я .communicate() с ним. Кажется, я отвечаю на мой первый .communicate() :

 >>> t = subprocess.Popen('trek', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) >>> t.communicate('\n') ('\n * * * STARTREK * * *\n\nPress return to continue.\nWhat length game: ', None) 

Но мне нужно иметь возможность читать stdout, чтобы иметь возможность выяснить, какой должен быть следующий stdin. Итак, как я могу отправить материал в stdin, не делая того, что говорит trek, что это конец его ввода?

EDIT: Кто-то предложил t.stdin.write() . Это работает, но теперь я не могу найти способ прочитать результаты:

 >>> t.stdin.write('\n') >>> t.poll() >>> t.stdout.read() 

Это вечно вечно:

 ^CTraceback (most recent call last): File "<stdin>", line 1, in <module> KeyboardInterrupt >>> t.stdout.readline() '' 

Итак, что теперь происходит?

One Solution collect form web for “Как мне взаимодействовать с консольным приложением, как будто я пользователь набираю в него что-то?”

Предполагая, что это linux, используйте модуль pexpect . Он написан для работы с интерактивными программами. Такие методы, как communication (), не работают, потому что они ждут выхода программы. Просто чтение не работает, потому что программа не покраснела, поэтому читать нечего. Вы можете создать свой собственный pty и использовать его при вызове Popen () или позволить pexpect выполнять эту работу за вас.

  • Отправка строк между скриптами Python с использованием подпроцессов PIPE
  • Запретить подпроцесс подпроцесса писать на stdout
  • Перенаправить stdout из python для вызовов C
  • Nohup и Python -u: он по-прежнему не регистрирует данные в реальном времени
  • Как увидеть stdout при запуске тестов Django?
  • Получение результата в реальном времени из ffmpeg для использования в индикаторе выполнения (PyQt4, stdout)
  • Python - перезагружает стандартный вывод stdout, после чего перенаправляет его в файл
  • Как вы передаете данные в STDIN программы из разных локальных / удаленных процессов в Python?
  • Python - лучший язык программирования в мире.