How to terminate process from Python using pid?

134,416

Solution 1

Using the awesome psutil library it's pretty simple:

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

If you don't want to install a new library, you can use the os module:

import os
import signal

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

See also the os.kill documentation.


If you are interested in starting the command python StripCore.py if it is not running, and killing it otherwise, you can use psutil to do this reliably.

Something like:

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'])

Sample run:

$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.

Note: In previous psutil versions cmdline was an attribute instead of a method.

Solution 2

I wanted to do the same thing as, but I wanted to do it in the one file.

So the logic would be:

  • if a script with my name is running, kill it, then exit
  • if a script with my name is not running, do stuff

I modified the answer by Bakuriu and came up with this:

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...

Running the script will do whatever the script does. Running another instance of the script will kill any existing instance of the script.

I use this to display a little PyGTK calendar widget which runs when I click the clock. If I click and the calendar is not up, the calendar displays. If the calendar is running and I click the clock, the calendar disappears.

Share:
134,416
Alex
Author by

Alex

Passionate about innovations. Invented some stuff. In the first 50 years of my life, didn't have to learn coding. But seems, now got to. In love with electronic engineering, music, chess, Linux, Python...aaaannnnd inventions! I like to help people, but not much - don't like to discomfort my selfishness.

Updated on February 10, 2021

Comments

  • Alex
    Alex about 3 years

    I'm trying to write some short script in python which would start another python code in subprocess if is not already started else terminate terminal & app (Linux).

    So it looks like:

    #!/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 )
    

    Have problem of lacking knowledge to name proces by pid which app reads from file ".proc". The other problem is that interpreter says that string named dat is not equal to "x" ??? What I've missed ?