web-dev-qa-db-ja.com

Python:バックグラウンドプロセスでpopen pollを使用する

私は長いプロセス(実際には別のpythonスクリプト)をバックグラウンドで実行しています。それがいつ終了したかを知る必要があります。Popen.poll()は常に0を返すことがわかりましたバックグラウンドプロセスこれを行う別の方法はありますか?

p = subprocess.Popen("sleep 30 &", Shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
a = p.poll()
print(a)

上記のコードはNoneを出力しません。

16
Code Slinger

シェルのバックグラウンドを使用する必要はありません&構文、subprocessはプロセスをバックグラウンドで単独で実行するため

通常どおりコマンドを実行してから、Popen.poll 戻り値 not None

import time
import subprocess

p = subprocess.Popen("sleep 30", Shell=True)
# Better: p = subprocess.Popen(["sleep", "30"])

# Wait until process terminates
while p.poll() is None:
    time.sleep(0.5)

# It's done
print "Process ended, ret code:", p.returncode
37
dbr

popen.wait()またはpopen.communicate()コマンドのどちらかが必要だと思います。 Communicateは、stdoutに入れたstderrおよびPIPEデータを取得します。他のアイテムがPythonスクリプトである場合、Shell=True呼び出しは次のように行います。

p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = p.communicate()
print(stdout)
print(stderr)

もちろん、これらはメインスレッドを保持し、他のプロセスが完了するのを待ちます。忙しく待ちたい場合は、元のコードをループでラップするだけです。 (元のコードでは、「None」が印刷されていました)

ループソリューションでのラッピングの例:

p = subprocess.Popen([python.call, "my", params, (go, here)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while p.poll() == None:
    # We can do other things here while we wait
    time.sleep(.5)
    p.poll()
(results, errors) = p.communicate()
if errors == '':
    return results
else:
    raise My_Exception(errors)
11
blackfedora

最後にアンパサンドを付けてスクリプトを実行しないでください。シェルはプロセスをフォークして0の終了コードを返すためです。

10
Fedor Gogolev