my_own_exe
というインタラクティブなプログラムがあります。最初にalive
を出力し、次にS\n
を入力してから、もう一度alive
を出力します。最後にL\n
を入力します。いくつかの処理を実行して終了します。
ただし、次のpythonスクリプトから呼び出すと、最初の「生きている」を出力した後、プログラムがハングしたように見えました。
ここの誰かがなぜこれが起こっているのか教えてもらえますか?
//フォローアップを読んだ後(ありがとう)、コードを次のように変更しました:
import subprocess
import time
base_command = "./AO_FelixStrategy_UnitTest --bats 31441 --chix 12467 --enxutp 31884 --turq 26372 --symbol SOGN --target_date " + '2009-Oct-16'
print base_command
proc2 = subprocess.Popen(base_command, Shell=True , stdin=subprocess.PIPE,)
time.sleep(2);
print "aliv"
proc2.communicate('S\n')
print "alive"
time.sleep(6)
print "alive"
print proc2.communicate('L\n')
time.sleep(6)
プログラムは最初の入力「S\n」でうまくいきますが、その後停止し、2番目の「L\n」はちょっと無視されます。
なぜこんな感じなのか、誰か教えてもらえますか?
プロセスとの対話:データをstdinに送信します。ファイルの終わりに達するまで、stdoutおよびstderrからデータを読み取ります。 プロセスが終了するのを待ちます。
したがって、communicate()
が実行された後、プロセスは終了しました。
プロセスが停止するのを待たずに書き込みと読み取りを行う場合:
ever_Shell=True
_を使用しないでください-それは針状にシェルを呼び出してプログラムを呼び出すので、あなたとあなたのプログラムの間に別のプロセスがあります。それには多くの不快な副作用があります。デフォルトは_Shell=False
_なので、これを維持する必要があります。 Popen
行を次のように変更します。
_p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
"--bats", "31441", "--chix", "12467",
"--enxutp", "31884", "--turq", "26372",
"--symbol", "SOGN", "--target_date", '2009-Oct-16'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
_
_p.stdin.write
_を使用してプロセスに書き込みます。 _p.stdout.read
_を使用して読み取ります。
p.stdout.read
_を呼び出すと、ブロックされます。書き込みバッファがいっぱいの場合に_p.stdin.write
_を呼び出すと、ブロックされます。したがって、読み取り/書き込みができるものがあることを確認する必要があります。これは、UNIXOSでselect
を使用して行います。 Windowsでは、残念ながらスレッドに頼らなければなりません。少なくともそれは_Popen.communicate
_が内部で行うことです。AO_FelixStrategy_UnitTest
_を記述しなかった場合は、さらに問題が発生する可能性があります:AO_FelixStrategy_UnitTest
_バッファを考慮する必要があることに注意してください。デフォルトでは、標準のC PIPE通信はバッファリングされているため、入力側を閉じるまで出力が表示されない場合があります(p.stdin.close()
を実行します。_AO_FelixStrategy_UnitTest
_が出力を定期的にフラッシュしない限り。説明内容に基づいたサンプルコードを次に示します。 _AO_FelixStrategy_UnitTest
_がどのように開発されたかによっては機能する可能性があります。
_p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
"--bats", "31441", "--chix", "12467",
"--enxutp", "31884", "--turq", "26372",
"--symbol", "SOGN", "--target_date", '2009-Oct-16'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
output = p.communicate('S\nL\n')[0]
print output
_
communicate()
stdoutおよびstderrからデータを読み取りますファイルの終わりに達するまで。 -プログラムが終了するまで待機します。
comunicateは1回だけ実行され、パイプを閉じるため、複数のコマンドを送信する場合これに、同じ文字列で次々に送信する必要があります。
これは、スレッド、subprocess32、stdin.write、stdout.readなどを試した後、私のために働いた例です。この情報は、公式のpython通信用の参照情報にはありません:- https://docs.python.org/2/library/subprocess.html
私がこれを見つけた唯一の場所はここでした: Pythonサブプロセス通信は私のプロセスを殺します
いずれにせよ、ここにコードがあります。シンプルで、スレッドもサブプロセスもありません32。LinuxとWindowsで動作します。はい、他のプロセスにコマンドを送信する回数を知っている必要がありますが、一般的にはそれを知っています。これに加えて、スレッド、cwd、Shell = True、またはその他の必要なものを追加できますが、これは最も単純なケースです。
def do_commands(self, cmd, parms):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE )
# wait for the process to terminate
out, err = process.communicate(cmd_parms)
errcode = process.returncode
return errcode, out, err
したがって、たとえば、呼び出されているアプリケーションに複数のキャリッジリターン(\ n)を送信し、途中のパラメータ(インタラクティブに気になります)を送信する場合は、次のように呼び出します。
cmd_parms = "\n\n\n\n\nparm\n\n"
errcode, out, err = do_commands(command, cmd_parms)