web-dev-qa-db-ja.com

pidを使用してPythonからプロセスを終了する方法は?

pythonで別のpythonが開始されていない場合はサブプロセスでコードを開始します。そうでない場合は端末とアプリを終了します(Linux) 。

次のようになります:

#!/usr/bin/python
from subprocess import Popen

text_file = open(".proc", "rb")
dat = text_file.read()
text_file.close()

def do(dat):

    text_file = open(".proc", "w")
    p = None

    if dat == "x" :

        p = Popen('python StripCore.py', Shell=True)
        text_file.write( str( p.pid ) )

    else :
        text_file.write( "x" )

        p = # Assign process by pid / pid from int( dat )
        p.terminate()

    text_file.close()

do( dat )

アプリがファイルから読み取るプロセスをpidで指定する知識が不足しているという問題があります"。proc"。もう1つの問題は、インタープリターがdatという名前の文字列が"x"に等しくないということです。私が逃したものは何ですか?

36
Alex

素晴らしい psutil ライブラリを使用すると、非常に簡単です。

p = psutil.Process(pid)
p.terminate()  #or p.kill()

新しいライブラリをインストールしたくない場合は、osモジュールを使用できます。

import os
import signal

os.kill(pid, signal.SIGTERM) #or signal.SIGKILL 

os.kill documentation も参照してください。


コマンドが実行されていない場合はpython StripCore.pyを開始し、そうでない場合は強制終了することに興味がある場合は、psutilを使用して確実にこれを行うことができます。

何かのようなもの:

import psutil
from subprocess import Popen

for process in psutil.process_iter():
    if process.cmdline() == ['python', 'StripCore.py']:
        print('Process found. Terminating it.')
        process.terminate()
        break
else:
    print('Process not found: starting it.')
    Popen(['python', 'StripCore.py'])

サンプル実行:

$python test_strip.py   #test_strip.py contains the code above
Process not found: starting it.
$python test_strip.py 
Process found. Terminating it.
$python test_strip.py 
Process not found: starting it.
$killall python
$python test_strip.py 
Process not found: starting it.
$python test_strip.py 
Process found. Terminating it.
$python test_strip.py 
Process not found: starting it.

:以前のpsutilバージョンではcmdlineattributeでしたメソッドの代わりに。

90
Bakuriu

と同じことをしたかったのですが、1つのファイルでやりたかったのです。

したがって、ロジックは次のようになります。

  • 私の名前のスクリプトが実行されている場合、それを終了して終了します
  • 私の名前のスクリプトが実行されていない場合、何かをする

バクリウの答えを修正して、これを思いつきました。

from os import getpid
from sys import argv, exit
import psutil  ## pip install psutil

myname = argv[0]
mypid = getpid()
for process in psutil.process_iter():
    if process.pid != mypid:
        for path in process.cmdline():
            if myname in path:
                print "process found"
                process.terminate()
                exit()

## your program starts here...

スクリプトを実行すると、スクリプトが実行することは何でも実行されます。スクリプトの別のインスタンスを実行すると、スクリプトの既存のインスタンスが強制終了されます。

これを使用して、時計をクリックすると実行される小さなPyGTKカレンダーウィジェットを表示します。クリックしてカレンダーが起動していない場合、カレンダーが表示されます。カレンダーが実行されているときに時計をクリックすると、カレンダーが消えます。

3
suprjami