Kill process by name?
Asked Answered
P

17

132

I'm trying to kill a process (specifically iChat). On the command line, I use these commands:

ps -A | grep iChat 

Then:

kill -9 PID

However, I'm not exactly sure how to translate these commands over to Python.

Pesthole answered 31/5, 2010 at 0:37 Comment(0)
L
94

Assuming you're on a Unix-like platform (so that ps -A exists),

>>> import subprocess, signal
>>> import os
>>> p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
>>> out, err = p.communicate()

gives you ps -A's output in the out variable (a string). You can break it down into lines and loop on them...:

>>> for line in out.splitlines():
...   if 'iChat' in line:
...     pid = int(line.split(None, 1)[0])
...     os.kill(pid, signal.SIGKILL)
... 

(you could avoid importing signal, and use 9 instead of signal.SIGKILL, but I just don't particularly like that style, so I'd rather used the named constant this way).

Of course you could do much more sophisticated processing on these lines, but this mimics what you're doing in shell.

If what you're after is avoiding ps, that's hard to do across different Unix-like systems (ps is their common API to get a process list, in a sense). But if you have a specific Unix-like system in mind, only (not requiring any cross-platform portability), it may be possible; in particular, on Linux, the /proc pseudo-filesystem is very helpful. But you'll need to clarify your exact requirements before we can help on this latter part.

Lugansk answered 31/5, 2010 at 0:50 Comment(5)
That worked very well! I'm running a Mac environment so I think this will be perfect. Thank you for all your help.Pesthole
Above works on .nix, but is not pythonic. The appro way, as posted below, is to use the os.system('taskkill /f /im exampleProcess.exe') approach, which is part of core python.Lyingin
@Jonesome: Your answer seems to be for Windows (due to the command syntax and the .exe filename), but the question seems to be for Mac OS.Batten
I prefer this answer to Giampaolo Rodolà's because, even though it is not very Pythonic, it works on Windows assuming you have Cygwin or Msys installed. psutil isn't present in Python 2.7.10 on Windows. Attempting to "pip install psutil" failed on my machine, saying that I needed to install Visual C++ 9.0. Screw that! I'd much rather install Cygwin or Msys.Goshorn
Works in Windows since Python 3.2, but usually signal will be the exit code of the killed process.Digiacomo
T
266

psutil can find process by name and kill it:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()
Thursday answered 19/11, 2010 at 23:11 Comment(11)
This. Because it is cross platform.Cockneyfy
or if you want by command line something like: if "your_python_script.py" in proc.cmdline: ..killAsben
The downside of this is that it requires the psutil package, that may not be present on the target machine.Holladay
@GiampaoloRodola: Doesn't the code shown (in your answer) fail when there is more than one process with the same name? E.g. just ran process_iter() on Windows and it shows multiple processes with the name() of 'chrome.exe' - as is expected, because Chrome does start many. In such a case, I suppose the only way is to identify which instance of those processes (with the same name) you want to kill, and kill it by pid.Batten
The solution above kills all process with that name (either 1 or many). Not sure I understand your question.Cerellia
@Bengt. This is not cross platform if you include Windows! psutil is not part of Python 2.7.10. And "pip install psutil" fails unless you install Visual C++ 9.0, which will be impractical in many cases. Still, congrats on your 17 upvotes :-)Goshorn
"pip install psutil" will work just fine as it will retrieve the wheel version on pypi. And no, you don't need a compiler.Cerellia
Ignoring getting the psutil to install on each OS, is the code itself really cross-platform? I don't think the process name on a Linux system is "python.exe", but just "python".Niche
Probably best to use proc.terminate() first, followed by proc.kill() after a time delay. terminate() uses SIGTERM and allows a process to clean up.Kmeson
I have a related problem, hope somebody will be able to help. I start my process using this code p = Process(name='MyProcess', target=long_running_func, args=(arg1,)) p.start() but when I use the above code from the answer like so: if proc.name() == 'MyProcess': psutil can't find it, I check using processId to find the process name python.exe, how do I solve this? I need to use my name and later search by itTerrill
It nearly iterated 500 processes, would it be faster to get its process id by using ps auxww | grep -E process name?Wintry
L
94

Assuming you're on a Unix-like platform (so that ps -A exists),

>>> import subprocess, signal
>>> import os
>>> p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
>>> out, err = p.communicate()

gives you ps -A's output in the out variable (a string). You can break it down into lines and loop on them...:

>>> for line in out.splitlines():
...   if 'iChat' in line:
...     pid = int(line.split(None, 1)[0])
...     os.kill(pid, signal.SIGKILL)
... 

(you could avoid importing signal, and use 9 instead of signal.SIGKILL, but I just don't particularly like that style, so I'd rather used the named constant this way).

Of course you could do much more sophisticated processing on these lines, but this mimics what you're doing in shell.

If what you're after is avoiding ps, that's hard to do across different Unix-like systems (ps is their common API to get a process list, in a sense). But if you have a specific Unix-like system in mind, only (not requiring any cross-platform portability), it may be possible; in particular, on Linux, the /proc pseudo-filesystem is very helpful. But you'll need to clarify your exact requirements before we can help on this latter part.

Lugansk answered 31/5, 2010 at 0:50 Comment(5)
That worked very well! I'm running a Mac environment so I think this will be perfect. Thank you for all your help.Pesthole
Above works on .nix, but is not pythonic. The appro way, as posted below, is to use the os.system('taskkill /f /im exampleProcess.exe') approach, which is part of core python.Lyingin
@Jonesome: Your answer seems to be for Windows (due to the command syntax and the .exe filename), but the question seems to be for Mac OS.Batten
I prefer this answer to Giampaolo Rodolà's because, even though it is not very Pythonic, it works on Windows assuming you have Cygwin or Msys installed. psutil isn't present in Python 2.7.10 on Windows. Attempting to "pip install psutil" failed on my machine, saying that I needed to install Visual C++ 9.0. Screw that! I'd much rather install Cygwin or Msys.Goshorn
Works in Windows since Python 3.2, but usually signal will be the exit code of the killed process.Digiacomo
U
44

If you have to consider the Windows case in order to be cross-platform, then try the following:

os.system('taskkill /f /im exampleProcess.exe')
Underlaid answered 26/7, 2012 at 0:54 Comment(2)
@alansiqueira27 Unfortunately it's only the Windows cmd case. You have to see above answers for cross platform solutions.Underlaid
This worked for my use case. Thanx! Note, that this is neat, it kills all the processes by that name so if you have multiple Y.exe's not terminating, all process id's of it will be terminated.Aback
A
23

If you have killall:

os.system("killall -9 iChat");

Or:

os.system("ps -C iChat -o pid=|xargs kill -9")
Aruabea answered 31/5, 2010 at 0:41 Comment(4)
There's also pkill, although I think I'm the only person in the world that uses it instead of killallGreeneyed
Ok cool, yea it looks like the first command worked perfect. Thanks for the help.Pesthole
@MichaelMrozek How can you live with the sweet feeling of typing things like killall java?Priscilapriscilla
@Michael I use pkill because the only killall I was aware of was the "kill everything" one.Overfeed
S
8

You can try this. but before you need to install psutil using sudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()
Sycosis answered 12/3, 2018 at 6:53 Comment(1)
at least this is portable, even if the accepted answer already describes this solution.Matchless
T
7

this worked for me in windows 7

import subprocess
subprocess.call("taskkill /IM geckodriver.exe")
Toro answered 12/12, 2016 at 16:35 Comment(0)
S
1

The below code will kill all iChat oriented programs:

p = subprocess.Popen(['pgrep', '-l' , 'iChat'], stdout=subprocess.PIPE)
out, err = p.communicate()

for line in out.splitlines():        
    line = bytes.decode(line)
    pid = int(line.split(None, 1)[0])
    os.kill(pid, signal.SIGKILL)
Stubby answered 21/9, 2011 at 9:1 Comment(0)
A
1

Get the process object using the Process.

>>> import psutil
>>> p = psutil.Process(23442)
>>> p
psutil.Process(pid=23442, name='python3.6', started='09:24:16')
>>> p.kill()
>>> 
Antinomian answered 8/10, 2020 at 9:27 Comment(0)
T
1

You can use the psutil module to kill a process using it's name. For the most part, this should be cross platform.

import traceback

import psutil


def kill(process_name):
    """Kill Running Process by using it's name
    - Generate list of processes currently running
    - Iterate through each process
        - Check if process name or cmdline matches the input process_name
        - Kill if match is found
    Parameters
    ----------
    process_name: str
        Name of the process to kill (ex: HD-Player.exe)
    Returns
    -------
    None
    """
    try:
        print(f'Killing processes {process_name}')
        processes = psutil.process_iter()
        for process in processes:
            try:
                print(f'Process: {process}')
                print(f'id: {process.pid}')
                print(f'name: {process.name()}')
                print(f'cmdline: {process.cmdline()}')
                if process_name == process.name() or process_name in process.cmdline():
                    print(f'found {process.name()} | {process.cmdline()}')
                    process.terminate()
            except Exception:
                print(f"{traceback.format_exc()}")

    except Exception:
        print(f"{traceback.format_exc()}")

I have basically extended @Giampaolo Rodolà's answer.

  • Added exception handling
  • Added check to see cmdline

I have also posted this snippet as a gist.

Note: You can remove the print statements once you are satisfied that the desired behavior is observed.

Tamtama answered 12/5, 2021 at 18:51 Comment(0)
P
0

you can use WMI module to do this on windows, though it's a lot clunkier than you unix folks are used to; import WMI takes a long time and there's intermediate pain to get at the process.

Pussyfoot answered 31/5, 2010 at 2:48 Comment(0)
U
0

If you want to kill the process(es) or cmd.exe carrying a particular title(s).

import csv, os
import subprocess
# ## Find the command prompt windows.
# ## Collect the details of the command prompt windows and assign them.
tasks = csv.DictReader(subprocess.check_output('tasklist /fi "imagename eq cmd.exe" /v /fo csv').splitlines(), delimiter=',', quotechar='"')
# ## The cmds with titles to be closed.
titles= ["Ploter", "scanFolder"]

# ## Find the PIDs of the cmds with the above titles.
PIDList = []
for line in tasks:
    for title in titles:
        if  title in line['Window Title']:
           print line['Window Title']       
           PIDList.append(line['PID'])

# ## Kill the CMDs carrying the PIDs in PIDList
for id in PIDList:
    os.system('taskkill /pid ' + id ) 

Hope it helps. Their might be numerous better solutions to mine.

Utopia answered 26/8, 2016 at 7:1 Comment(0)
O
0

The Alex Martelli answer won't work in Python 3 because out will be a bytes object and thus result in a TypeError: a bytes-like object is required, not 'str' when testing if 'iChat' in line:.

Quoting from subprocess documentation:

communicate() returns a tuple (stdout_data, stderr_data). The data will be strings if streams were opened in text mode; otherwise, bytes.

For Python 3, this is solved by adding the text=True (>= Python 3.7) or universal_newlines=True argument to the Popen constructor. out will then be returned as a string object.

import subprocess, signal
import os

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE, text=True)
out, err = p.communicate()

for line in out.splitlines():
    if 'iChat' in line:
        pid = int(line.split(None, 1)[0])    
        os.kill(pid, signal.SIGKILL)

Alternatively, you can create a string using the decode() method of bytes.

import subprocess, signal
import os

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
out, err = p.communicate()

for line in out.splitlines():
    if 'iChat' in line.decode('utf-8'):
        pid = int(line.split(None, 1)[0])    
        os.kill(pid, signal.SIGKILL)
Occupier answered 25/5, 2020 at 21:9 Comment(0)
W
0

In the same style as Giampaolo Rodolà' answer but as one liner, case insensitive and without having to match the whole process name, in windows you would have to include the .exe suffix.

[x.kill() for x in psutil.process_iter() if 'ichat' in x.name().lower()]
Willy answered 18/1, 2021 at 5:20 Comment(0)
O
-1

For me the only thing that worked is been:

For example

import subprocess
proc = subprocess.Popen(["pkill", "-f", "scriptName.py"], stdout=subprocess.PIPE)
proc.wait()
Outpost answered 22/9, 2014 at 13:19 Comment(0)
S
-1
import os, signal

def check_kill_process(pstring):
    for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"):
        fields = line.split()
        pid = fields[0]
        os.kill(int(pid), signal.SIGKILL)
Shenashenan answered 29/11, 2019 at 6:12 Comment(0)
W
-2

You can use pkill <process_name> in a unix system to kill process by name.

Then the python code will be:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)
Willpower answered 31/5, 2010 at 1:28 Comment(1)
All the the systems I'm using are Mac and when I try to run pkill it's just telling me that the command cannot be found.Pesthole
A
-2
import psutil
pid_list=psutil.get_pid_list()
print pid_list
p = psutil.Process(1052)
print p.name
for i in pid_list:
    p = psutil.Process(i)
    p_name=p.name
    print str(i)+" "+str(p.name)
    if p_name=="PerfExp.exe":
        print "*"*20+" mam ho "+"*"*20
        p.kill()
Aframe answered 11/1, 2013 at 10:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.