Stupid.Fat.Cat
Stupid.Fat.Cat

Reputation: 11325

Killing process by command in python

I'm trying to avoid killing the process like so:

import subprocess
command = "pkill python"
process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)

but instead I'm trying to kill a particular process, not all python processes. Say that the process command is called "python test.py" I want to kill that one, and leave the other python processes intact. Not sure how I would go about doing this.

Platform is Linux/Ubuntu

To clarify, this is what I'm trying to accomplish, when I perform a ps -aux | grep "python" I see this:

sshum    12115 68.6  2.7 142036 13604 pts/0    R    11:11   0:13 python test.py &
sshum    12128  0.0  0.1  11744   904 pts/0    S+   11:12   0:00 grep --color=auto test.py

I want to kill process 12115, but I'm not sure how I would go about doing this without killing all the other python processes at the same time.

EDIT: This is the solution that I came up with, but it doesn't look particularly elegant...

command = "ps aux"
process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
output = process.communicate()[0].split("\n")
try:
    for p in output:
        if "python test.py" in p:
            l = p.split(" ")
            l = [x for x in l if x!='']
            pid = int(l[1])
            os.kill(pid, 9)
except:
    pass

Upvotes: 0

Views: 2450

Answers (1)

ShadowKyogre
ShadowKyogre

Reputation: 21

There's a flag in pgrep (-f) that allows searching the entire commandline for a process, not just the name.

Output of ps aux|grep python on my machine while trying to reproduce your result:

shadowk+  1194  2.4  0.5 354240 70748 ?        S    11:29   0:46 /usr/bin/python /usr/share/chronoslnx/main.py
shadowk+  1239  0.1  0.6 508548 84080 ?        Sl   11:29   0:03 /usr/bin/python2 /usr/share/kupfer/kupfer.py
shadowk+  1245  0.0  0.4 296732 60956 ?        S    11:29   0:00 /usr/bin/python2 -O /usr/share/wicd/gtk/wicd-client.py --tray
shadowk+  2279 99.7  0.0  22800  7372 pts/3    R+   12:00   0:30 /usr/bin/python ./test.py
shadowk+  2289  0.0  0.0  10952  2332 pts/0    S+   12:01   0:00 grep --color=auto python

In my case, any of these commands would get the PID for the ./test py file that's running:

pgrep -f 'python ./test.py'
pgrep -f 'test.py'

The second one's closer to what you're looking for, so the adjusted code looks like this (for Python 2.x, you just need to remove the .decode() calls from e.output and the call to get the PID):

import subprocess
import os
try:
    needed_pid=subprocess.check_output(['pgrep','-f','test.py']).decode()
except subprocess.CalledProcessError as e:
    print("pgrep failed because ({}):".format(e.returncode) , e.output.decode())
else:
    try:
        os.kill(int(needed_pid), 9)
        print("We killed test.py!")
    except ProcessLookupError as e:
        print("We tried to kill an old entry.")
    except ValueError as e:
        print("Well, there's no test.py...so...yeah.")

You could also do it more simply like this if you want to call pkill directly to do the same thing:

import subprocess
subprocess.call(['pkill', '-f', 'test.py'])

Upvotes: 1

Related Questions