126

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.

martineau
  • 119,623
  • 25
  • 170
  • 301
Aaron
  • 2,672
  • 10
  • 28
  • 45

17 Answers17

258

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()
Giampaolo Rodolà
  • 12,488
  • 6
  • 68
  • 60
  • 61
    This. Because it is **cross platform**. – Bengt Jul 05 '13 at 12:40
  • 2
    or if you want by command line something like: if "your_python_script.py" in proc.cmdline: ..kill – OWADVL Oct 25 '13 at 10:31
  • 12
    The downside of this is that it requires the `psutil` package, that may not be present on the target machine. – CadentOrange Aug 05 '14 at 07:29
  • @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. – Vasudev Ram Feb 19 '16 at 19:01
  • The solution above kills all process with **that** name (either 1 or many). Not sure I understand your question. – Giampaolo Rodolà Feb 19 '16 at 23:06
  • 1
    @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 :-) – Andrew Bainbridge Apr 04 '16 at 16:58
  • 7
    "pip install psutil" will work just fine as it will retrieve the wheel version on pypi. And no, you don't need a compiler. – Giampaolo Rodolà Apr 05 '16 at 01:06
  • 1
    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". – MrD Feb 08 '18 at 20:56
  • 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. – gerardw Jan 22 '21 at 09:56
  • 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 it – Prince Apr 01 '21 at 16:58
  • It nearly iterated 500 processes, would it be faster to get its process id by using `ps auxww | grep -E process name`? – alper Oct 31 '21 at 12:19
93

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.

blkrt
  • 297
  • 1
  • 6
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 1
    That worked very well! I'm running a Mac environment so I think this will be perfect. Thank you for all your help. – Aaron May 31 '10 at 01:25
  • 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. – Jonesome Reinstate Monica Feb 13 '15 at 17:00
  • @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. – Vasudev Ram Feb 19 '16 at 20:02
  • 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. – Andrew Bainbridge Apr 04 '16 at 16:54
  • Works in Windows since Python 3.2, but usually signal will be the exit code of the killed process. – Cees Timmerman Feb 08 '18 at 11:59
43

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')
limitcracker
  • 2,208
  • 3
  • 24
  • 23
  • @alansiqueira27 Unfortunately it's only the Windows cmd case. You have to see above answers for cross platform solutions. – limitcracker Sep 01 '18 at 04:34
  • 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. – MathCrackExchange Jan 09 '20 at 20:12
24

If you have killall:

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

Or:

os.system("ps -C iChat -o pid=|xargs kill -9")
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
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()
7

this worked for me in windows 7

import subprocess
subprocess.call("taskkill /IM geckodriver.exe")
d0dulk0
  • 112
  • 2
  • 8
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()
>>> 
SuperNova
  • 25,512
  • 7
  • 93
  • 64
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.

Ayush Mandowara
  • 490
  • 5
  • 18
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)
Poobalan
  • 309
  • 1
  • 3
  • 5
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.

amwinter
  • 3,121
  • 2
  • 27
  • 25
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.

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)
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()]
Cesc
  • 904
  • 1
  • 9
  • 17
-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()
Marco Mac
  • 79
  • 2
  • 10
-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)
-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()
Taryn
  • 242,637
  • 56
  • 362
  • 405
-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)
xaph
  • 663
  • 5
  • 15
  • 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. – Aaron May 31 '10 at 01:33