2013-05-31 19 views
11

私はsubprocessのプログラムをPythonで起動しています。実行中のサブプロセスコールを終了する

場合によっては、プログラムがフリーズすることがあります。これは私のコントロール外です。コマンドラインから実行できるのは、CtrlEscです。プログラムをすばやく削除します。

subprocessでこれをエミュレートする方法はありますか?私はsubprocess.Popen(cmd, shell=True)を使ってプログラムを立ち上げています。

答えて

15
p = subprocess.Popen("echo 'foo' && sleep 60 && echo 'bar'", shell=True) 
p.kill() 

詳細はsubprocessモジュールのドキュメントをチェックアウト:Popen.terminate()Popen.kill()、送信:http://docs.python.org/2/library/subprocess.html

+2

おそらく、完全に殺す前に終了する必要があります。 – Gewthen

+1

終了して終了しようとすると、サブプロセスがまだ実行されています!! – hungryWolf

+0

これはおそらくshell = Trueのためです –

20

まあ、使用のものであってもよいsubprocess.Popen()によって返されたオブジェクトのメソッドのカップルがありますそれぞれSIGTERMおよびSIGKILLである。例えば

...

import subprocess 
import time 

process = subprocess.Popen(cmd, shell=True) 
time.sleep(5) 
process.terminate() 

は... 5秒後にそのプロセスを終了させます。

それとも...

import subprocess 
import time 
import os 
import signal 

process = subprocess.Popen(cmd, shell=True) 
time.sleep(5) 
os.kill(process.pid, signal.SIGINT) 
+2

Windowsでは 'kill = terminate'とシグナルは同じように動作しません。 – jfs

1

であなたの質問があまりにも明確ではないが、私はあなたが起動しようとしていることを前提としていた場合は、CTRL-CをシミュレートするSIGINTのように、他の信号を送信するためにos.kill()を使用することができますゾンビに行くプロセスはあなたのスクリプトのいくつかの状態でそれを制御できるようにしたい。この場合、私はあなたに以下を提案します:

p = subprocess.Popen([cmd_list], shell=False) 

これは本当にシェルを通過することをお勧めしません。 私はあなたがシェル= Falseを使用することをお勧めします。

# Get the process id & try to terminate it gracefuly 
pid = p.pid 
p.terminate() 

# Check if the process has really terminated & force kill if not. 
try: 
    os.kill(pid, 0) 
    p.kill() 
    print "Forced kill" 
except OSError, e: 
    print "Terminated gracefully" 
+0

- p.pidはPopenインスタンスのプロパティであり、メソッドではありません - OSErrorが発生するのは正確ですか?単純なPopenの場合でも、 (subprocess.Popen( "ls"、shell = False))という例外的な文は出てこないようです。 – bergercookie

+0

それは正しいです、pidはプロパティです、それはタイピングエラーでなければなりません。 OSErrorの場合、pidがもう存在しない場合、os.kill(pid、0)ステップで例外が発生します.p.terminate()はpidを成功させて終了しました;-) – ScotchAndSoda

0

2つのシグナルを使用して、実行中のサブプロセス呼び出し、つまりsignal.SIGTERMとsignal.SIGKILLを終了できます。たとえば

import subprocess 
import os 
import signal 
import time 
.. 
process = subprocess.Popen(..) 
.. 
# killing all processes in the group 
os.killpg(process.pid, signal.SIGTERM) 
time.sleep(2) 
if process.poll() is None: # Force kill if process is still alive 
    time.sleep(3) 
    os.killpg(process.pid, signal.SIGKILL) 
関連する問題