2017-09-16 21 views
2

Python 3.5を使ってインタラクティブコマンドラインアプリケーションとのインターフェースを探しています。アイデアは、私がPythonスクリプトの初めにプロセスを開始し、それを開いたままにしておくことです。ループでは、ファイルパスを出力し、その後に改行が続き、stdinになります。プロセスが完了するまで1/4秒待ってから、改行に達するまでstdoutから読み取ります。Pythonサブプロセス:stdinに出力し、改行までstdoutを読んで、繰り返してください。

communicateの機能は、subprocessと非常によく似ていますが、プロセスが終了するのを待つのではなく、リターンを待っています。これを行うための比較的簡単な方法を知っている人は誰ですか?

編集:可能であれば、pexpectなどのサードパーティライブラリではなく、標準ライブラリを使用することをお勧めします。

+4

'pexpect'モジュールを見ましたか? –

+0

@JonClements私はこれまでSSHのために使ってきました。しかし、私はこれについて調べます。ありがとうございました! –

+0

まだ... 'pexpect'を使用してください。標準的なライブラリの使用を推奨できない理由は非常に複雑です。 –

答えて

2

これにはsubprocess.Popenを使用できます。

このような何か:

proc = subprocess.Popen(['my-command'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

proc.stdinproc.stdoutは、サブプロセスの標準入力にデータを送信し、サブプロセスの標準出力から読み取るパイプのあなたの端です。

改行で終わる行だけを読むことに興味があるので、おそらくバッファリングによる問題を回避することができます。バッファリングは、サブプロセスを使用してインタラクティブなプロセスと通信するときの大きな問題の1つです。通常、I/Oはラインバッファーです。つまり、サブプロセスが改行を含む行を終了しない場合は、proc.stdoutにデータが表示されず、逆の場合はproc.stdinに書き込まれます。改行で終わらないバッファリングをオフにすることはできますが、それは単純ではなく、プラットフォームに依存しません。

解決しなければならないもう1つの問題は、サブプロセスが入力を待っているかどうか、パイプからの書き込みと読み取り以外の出力を行ったかどうかを判断できないことです。したがって、両方のプロセスがパイプI/O上でブロックされているため、proc.stdoutの出力を待ち、同時にデッドロックに陥ることなくproc.stdinに書き込むために、2番目のスレッドを開始する必要があります(Unixファイルハンドルでselectをサポートする場合は、selectを使用して、どのパイプを受信準備ができているか、または読み込みの準備ができているかを判断します。

0

これはイベントループの仕事のようです。 subprocessモジュールは、複雑なタスクの下でその歪みを示し始めます。

私は次のことをサブクラス化することで、ツイストでこれをやった:ツイスト用

twisted.internet.endpoints.ProcessEndpoint 
twisted.protocols.basic.LineOnlyReceiver 

ほとんどのドキュメントでは、エンドポイントとしてソケットを使用していますが、それはプロセスのコードを調整することは難しいことではありません。

関連する問題