0

bsdgames trek プログラムと対話する Python プログラムを作成しようとしています。それはクリンゴンとのゾークのようなものです:

   * * *   S T A R   T R E K   * * *

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   * * *   S T A R   T R E K   * * *\n\nPress return to continue.\nWhat length game: ', None)

しかし、次の標準入力がどうあるべきかを理解できるようにするには、標準出力を読み取ることができる必要があります。では、入力の終わりであることをトレックに伝えていることを何もせずに、標準入力に送信するにはどうすればよいですか?

編集:誰かが提案し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()
''

それで、今何が起こっているのですか?

4

1 に答える 1

1

これが Linux であると仮定すると、pexpectモジュールを使用します。インタラクティブなプログラムを扱うために書かれています。communicate() のような手法は、プログラムが終了するのを待つため機能しません。プログラムがスタウトをフラッシュしていないため、読み取るものが何もないため、単に読み取るだけでは機能しません。独自の pty を作成し、それを Popen() の呼び出し時に使用するか、pexpect に任せることができます。

于 2013-04-27T19:10:11.457 に答える