2

文字列をプログラムに送信してバックグラウンドで実行する python スクリプトを作成しようとしています。コマンド ラインで、次のコードをコピーして貼り付けると、Python プログラムに実行させたいことを正常に実行できます。

printf "f\nil\ncs\n1.e-8 100.0 1.e-8\nn\n0.002\nb\n0.05\nz\n2.e-7\nx4\n5.e-7\n\n\nfort.13\nn\nn\n\n" | vpfit95

ここで:vpfit95は、PATH 内の実行可能プログラムへのエイリアスです。

私が試したことのいくつかの順列(一度に1つずつ試しました):

import subprocess
vpfitExecutable = 'vpfit95'

String1=r'f\nil\ncs\n1.e-8 100.0 1.e-8\nn\n0.002\nb\n0.05\nz\n2.e-7\nx4\n5.e-7\n\n\nfort.13\nn\nn\n\n'
String2=r"f\nil\ncs\n1.e-8 100.0 1.e-8\nn\n0.002\nb\n0.05\nz\n2.e-7\nx4\n5.e-7\n\n\nfort.13\nn\nn\n\n"
String3="f\nil\ncs\n1.e-8 100.0 1.e-8\nn\n0.002\nb\n0.05\nz\n2.e-7\nx4\n5.e-7\n\n\nfort.13\nn\nn\n\n"

cmd1 = "printf \"" + String1 + "\"" 
cmd2 = "printf \"" + String1 + "\" | " + vpfitExecutable 
cmd3 = "printf \"" + String2 + "\"" 
cmd4 = "printf \"" + String3 + "\"" 

print cmd2

p1 = subprocess.Popen([vpfitExecutable, cmd1])
p2 = subprocess.Popen([cmd2])
p3 = subprocess.Popen([vpfitExecutable, cmd3])
p4 = subprocess.Popen([vpfitExecutable, cmd4])
p4 = subprocess.Popen([vpfitExecutable, String1])
p5 = subprocess.Popen([vpfitExecutable, String2])
p6 = subprocess.Popen([vpfitExecutable, String3])

# check
p7 = subprocess.Popen([vpfitExecutable]) # works.

そしてすべて失敗します(p7を除く)。「Fortran ランタイム エラー: ファイルの終わり」(vpfit プログラムによるもの) で失敗するものもあります。その他は、サブプロセス ライブラリへのトレースバックと「OSError: [Errno 2] No such file or directory」で失敗します。

いくつかのチェック:印刷cmd2してコピーして端末に貼り付けると、完全に機能します。を実行するp7と、文字列が渡されなくても、期待どおりにプログラムの実行が正しく開始されます。ここでは明らかに基本的なことが欠けていますが、それが何かわかりません。どんな助けでも大歓迎です!

4

1 に答える 1

6

はい、基本的なものが欠けています - パイプはシェルによって処理されます。サブプロセスで必要なことを行うにはvpfit95、サブプロセスとして実行してから、サブプロセスで実行する必要がありcommunicateます。ドキュメントのセクション 17.1.4.2 を参照して、シェル パイプラインを置き換えてください。

proc = subprocess.Popen([vpfitExecutable], stdin=subprocess.PIPE)
proc.communicate(input='your string') 

vpfit の stdout と stderr を検査する必要がある場合は、 の出力タプルからハンドルを取得しますcommunicate

汚い代替手段は、でコマンドを実行することです。これによりshell=True、シェル内でコマンドが生成され、コマンドでパイプを使用できますが、「仲介者を切り取って」サブプロセスと直接やり取りする方がクリーンです。

于 2012-07-17T07:17:48.820 に答える