2017-03-01 7 views
1

これで1時間以上を検索して実験しましたが、ここでは「ここの文書」を作成して、行ごとに出力を得る方法はないようです:Python Popen _with_リアルタイム入出力制御

python = '''var="some character text" 
print(var) 
print(var) 
exit() 
''' 

from subprocess import Popen, PIPE, STDOUT 
import shlex 

def run_process(command): 
    p = Popen(shlex.split(command), stdin=PIPE, stdout=PIPE, stderr=STDOUT) 
    p.stdin.write(python) 
    while True: 
    output = p.stdout.readline() 
    if output == '' and p.poll() is not None: 
     break 
    if output: 
     print output.strip() 
    rc=p.poll() 
    return rc 

run_process("/usr/bin/python") 

上記コードは無期限にハングします。はい、それは尾を食べる蛇ですが、それは概念を証明することだけでした。

問題は私のサブプロセスが実行に時間がかかり、何か問題があるかどうかを判断するために何時間も待たずに出力を見ることができる必要があるということです。何かヒント?ありがとう。

+0

は、その 'stdin.readline'なく – rakesh

+0

周りotherway' 'process.pollは()' 'であるべきあなたは確信していますエラー(2か所で) - その名前で変数がありません。 – jasonharper

+0

わかりません。 p.stdin.write()呼び出しとp.stdout.readline()呼び出しがありますが、コードにstdin.readline()はありません。また、私はprocess.poll()を持っていません - 私はオブジェクトを持っていますポーリング()メソッドを持つp。 – signal7

答えて

0

対話モード対非対話モードで実行すると、Pythonインタプリタの動作が異なります。 python(1)マニュアルページから:

非対話モードでは、入力全体が解析されてから実行されます。

もちろん、「入力全体」はEOFで区切られており、プログラムはEOFを送信しないため、ハングアップします。

Pythonは、その標準入力がis a ttyの場合、対話モードで動作します。 Ptyprocessライブラリを使用して、ttyをstdinとしてプロセスを起動することができます。またはPexpectライブラリ(Ptyprocessに基づく)を使用してください。これには、Pythonやその他のプログラムにはready-made REPL wrappersも含まれています。


しかし、あなたがSEDでのPythonを交換した場合 - もちろん、インタラクティブモードを持っていない - プログラムはまだ動作しません:

sed = '''this is a foo!\n 
another foo!\n 
''' 

from subprocess import Popen, PIPE, STDOUT 
import shlex 

def run_process(command): 
    p = Popen(shlex.split(command), stdin=PIPE, stdout=PIPE, stderr=STDOUT) 
    p.stdin.write(sed) 
    while True: 
    output = p.stdout.readline() 
    if output == '' and p.poll() is not None: 
     break 
    if output: 
     print output.strip() 
    rc=p.poll() 
    return rc 

run_process("/bin/sed -e 's/foo/bar/g'") 

これは別の問題によって引き起こされます。出力sedのバッファリング。一部のプログラムには、バッファリングを無効にするオプションがあります。具体的には、sedのとPythonの両方がこの問題を解決-uオプションを持っている:

run_process("/bin/sed -ue 's/foo/bar/g'") 
+0

それを指摘してくれてありがとう。私は明日、 'cat'と再テストし、違うかどうかを調べます。 – signal7

+0

これは私の問題を解決しました。 p.stdin.write()の後にp.stdin.close()を呼び出すと、これは期待通りに動作するようになりました。ありがとう。 – signal7