2016-05-11 10 views
0

私はpythonコードを持っています。私はそれをperlに変換する必要がありますが、残念ながら私はperlではうまくいきません。 STDOUTとSTDERRで特定の単語をチェックしたいと思います。ここでは、Pythonのコードは次のとおりです。PerlへのPythonコード

p = subprocess.Popen("bmod -b " + beginTime + " " + job_id + "; exit 1;", 
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 

while p.poll() is None: 
    err = p.stderr.readline().decode('utf_8') 
    out = p.stdout.readline().decode('utf_8') 
    if "changed" in err or "changed" in out: 
     subprocess.Popen("echo rescheduling was successful!", shell=True) 
os._exit(0) 

私はいくつかのドキュメンテーションを読んでのopen3機能がここで働いてますが、p.poll()の部分は私が何を使用するかわかりません。直後にメッセージ"rescheduling was successful!"を印刷することが重要である場合

+3

は、Perlで外部プロセスからの出力を読み込むには、いくつかの方法がありますが、最も単純なのは['qx()'](http://perldoc.perl.org/perlop.html#qx%2f_STRING_%2f)、[パイプで開く '](http://perldoc.perl.org/perlipc .html#open%28%for 29-for-IPC)、そして[Capture :: Tiny](https://metacpan.org/pod/Capture::Tiny)のようなものです。 'qx'と' open'に対しては、STDOUTとSTDERRの両方をチェックしたいので、STDERRをリダイレクトする必要があります。 – ThisSuitIsBlackNot

+2

'open3' +' select'が低すぎます。 IPC :: Run3の 'run3'またはIPC :: Runの' run'を使用してください。 – ikegami

+0

@ikegami出力を待つためにこのようなものを使うべきですか? '$ pid = run3'または' $ pid = open3' 'wait($ pid、0)' –

答えて

3

答えが依存(bmodがまだ実行されている場合)またはbmodが終了した後に、ラインを印刷するのに十分である場合にはラインがbmodから印刷されました。

最後のケースは、例えば、Perlで達成することは非常に簡単です:

my $out = qx/bmod -b $beginTime $job_id 2>&1/; 
say "rescheduling was successful!" if $out =~ /changed/; 

最初のケースについて、あなたは(bmodが終了する前であっても)すぐにメッセージを出力する必要がある場合は、最初のノートということPythonスクリプトが正しく動作していない可能性があります。 p.stderr.readline()行は、p.stdout.readline()のように、行がp.stdoutから読み取られる準備ができるまで同様にp.stderrから読み取る準備ができるまでスクリプトをブロックします。したがって、bmodstdoutにのみ印刷され、何もstderrに送られない場合、スクリプトは最初にp.stderr.readline()を呼び出したときにハングアップし、bmodが終了したときにのみ戻ります。

私はPythonでこれを正しく行う方法がわかりませんが、と組み合わせたIPC::Open3をPerlで使うことができます。またPerl select return “bad file descriptor” error

注意:例えば参照Perlで簡単なソリューションを使用してachivedすることができopenstderr場合とstdoutマージされています

my $pid = open (my $fh, '-|', "bmod -b $beginTime $job_id 2>&1") or die "Could not run command: $!"; 
while (my $line = <$fh>) { 
    print $line if $line =~ /changed/; 
} 
close $fh; 
関連する問題