按名称结束进程?

129

我想要关闭一个进程(具体来说是iChat)。在命令行中,我使用以下命令:

ps -A | grep iChat 

那么:

kill -9 PID

不过,我不太确定如何将这些命令翻译成Python。

17个回答

263

psutil 能够通过进程名找到进程并将其终止:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()

62
这个。因为它是跨平台的。 - Bengt
2
如果您想通过命令行执行此操作,可以使用以下代码:if "your_python_script.py" in proc.cmdline: ..kill。 - OWADVL
12
这样做的缺点是需要安装psutil包,但目标计算机上可能没有该包。 - CadentOrange
7
"pip install psutil" 将能很好地运行,因为它将从pypi上检索到适用的wheel版本。而且,不需要编译器。 - Giampaolo Rodolà
1
忽略在每个操作系统上安装psutil,这段代码本身真的是跨平台的吗?我认为Linux系统上的进程名称不是“python.exe”,而只是“python”。 - MrD
显示剩余6条评论

94

假设您使用的是类Unix平台(因为存在ps -A命令),

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

ps -A的输出保存为out变量(字符串)。 您可以将其分解为行并对其进行循环...

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

你可以避免导入signal,而是使用9代替signal.SIGKILL,但我不是特别喜欢那种风格,所以我宁愿用这种命名常量的方式。

当然,你可以在这些行上进行更复杂的处理,但这模仿了你在shell中所做的。

如果你想避免使用ps,跨不同的类Unix系统可能很难(ps是它们获取进程列表的公共API)。 但如果你只考虑特定的类Unix系统(不需要任何跨平台可移植性),那么可能是可行的;尤其是在Linux上,/proc伪文件系统非常有帮助。 但在我们能够帮助你解决后面的问题之前,你需要更明确地阐明你的具体要求。


1
那个很好用!我在使用Mac环境,所以我觉得这将是完美的。感谢您所有的帮助。 - Aaron
以上适用于 .nix,但不符合 Python 的风格。如下发布的 appro 方法是使用 os.system('taskkill /f /im exampleProcess.exe') 方法,这是 Python 核心的一部分。 - Jonesome Reinstate Monica
@Jonesome:你的回答似乎是针对Windows的(由于命令语法和.exe文件名),但问题似乎是针对Mac OS的。 - Vasudev Ram
我更喜欢这个答案,而不是Giampaolo Rodolà的答案,因为即使它不是很Pythonic,但假设您已安装了Cygwin或Msys,它可以在Windows上运行。在Windows上的Python 2.7.10中不存在psutil。尝试“pip install psutil”失败了,说我需要安装Visual C++ 9.0。算了吧!我宁愿安装Cygwin或Msys。 - Andrew Bainbridge
自Python 3.2起在Windows上运行,但通常信号将是被终止进程的退出代码。 - Cees Timmerman

43

如果你需要考虑到跨平台的情况,包括 Windows 平台,那么尝试以下方法:

os.system('taskkill /f /im exampleProcess.exe')

@alansiqueira27 很遗憾,这只是针对Windows cmd的情况。您必须查看上面的答案以获取跨平台解决方案。 - limitcracker
这对我的使用情况有效。谢谢!请注意,这很整洁,它会终止该名称的所有进程,因此如果您有多个Y.exe未终止,则其所有进程ID都将被终止。 - D Left Adjoint to U

24

如果您有killall命令:

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

或者:

os.system("ps -C iChat -o pid=|xargs kill -9")

10
还有pkill,尽管我认为我是世界上唯一使用它而不是killall的人。 - Michael Mrozek
1
好的,很酷,是的,看起来第一个命令完美地运行了。感谢您的帮助。 - Aaron
1
@MichaelMrozek 你怎么能忍受输入 killall java 这样的代码,然后享受那种甜蜜的感觉呢? - Alois Mahdal
@Michael 我使用 pkill,因为我知道的唯一一个 killall 是“杀死所有”的命令。 - Kyle Strand

8
你可以尝试这个。 但在此之前,你需要安装 psutil,使用 sudo pip install psutil
import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()

1
至少这是可移植的,即使已经有了接受的答案描述这个解决方案。 - Jean-François Fabre

7

这个在Windows 7里对我起作用了。

import subprocess
subprocess.call("taskkill /IM geckodriver.exe")

1
以下代码将杀死所有面向iChat的程序:
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)

1
您可以使用psutil模块按名称终止进程。在大多数情况下,这应该是跨平台的。
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()}")

我基本上扩展了@Giampaolo Rodolà的答案

  • 添加了异常处理
  • 添加了检查以查看命令行

我还将此片段发布为gist

注意:一旦确认观察到所需的行为,您可以删除打印语句。


1
使用 Process 获取进程对象。
>>> import psutil
>>> p = psutil.Process(23442)
>>> p
psutil.Process(pid=23442, name='python3.6', started='09:24:16')
>>> p.kill()
>>> 

0
如果你想结束一个特定标题的进程或cmd.exe。
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 ) 

希望这有所帮助。可能会有许多比我的更好的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接