【问题标题】:Kill process by name?按名称杀死进程?
【发布时间】:2011-02-25 19:39:44
【问题描述】:

我正在尝试终止一个进程(特别是 iChat)。在命令行上,我使用这些命令:

ps -A | grep iChat 

然后:

kill -9 PID

但是,我不确定如何将这些命令转换为 Python。

【问题讨论】:

    标签: python process kill


    【解决方案1】:

    psutil 可以通过名称找到进程并杀死它:

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

    【讨论】:

    • 这个。因为它是跨平台
    • 或者如果你想通过命令行类似: if "your_python_script.py" in proc.cmdline: ..kill
    • 这样做的缺点是它需要psutil 包,目标机器上可能不存在。
    • @Bengt。如果您包含 Windows,则这不是跨平台! psutil 不是 Python 2.7.10 的一部分。除非您安装 Visual C++ 9.0,否则“pip install psutil”会失败,这在许多情况下是不切实际的。不过,恭喜您获得 17 次支持 :-)
    • "pip install psutil" 可以正常工作,因为它会在 pypi 上检索轮子版本。不,你不需要编译器。
    【解决方案2】:

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

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

    out 变量(字符串)中为您提供ps -A 的输出。您可以将其分解为行并循环...:

    >>> 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 伪文件系统非常有用。但是,您需要先明确您的确切要求,然后我们才能在后面的部分提供帮助。

    【讨论】:

    • 效果很好!我正在运行 Mac 环境,所以我认为这将是完美的。感谢您的所有帮助。
    • 以上适用于.nix,但不是pythonic。如下所示,批准的方法是使用 os.system('taskkill /f /im exampleProcess.exe') 方法,它是核心 python 的一部分。
    • @Jonesome:您的答案似乎适用于 Windows(由于命令语法和 .exe 文件名),但问题似乎适用于 Mac OS。
    • 我更喜欢这个答案而不是 Giampaolo Rodolà 的答案,因为即使它不是非常 Pythonic,它也适用于 Windows,前提是您安装了 Cygwin 或 Msys。 psutil 在 Windows 上的 Python 2.7.10 中不存在。在我的机器上尝试“pip install psutil”失败,说我需要安装 Visual C++ 9.0。去他妈的!我宁愿安装 Cygwin 或 Msys。
    • 自 Python 3.2 起在 Windows 中工作,但通常信号将是被终止进程的退出代码。
    【解决方案3】:

    如果您必须考虑 Windows 案例才能跨平台,请尝试以下操作:

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

    【讨论】:

    • @alansiqueira27 不幸的是,这只是 Windows cmd 的情况。对于跨平台解决方案,您必须看到上述答案。
    • 这适用于我的用例。谢谢!请注意,这很简洁,它会杀死 所有 该名称的进程,因此如果您有多个 Y.exe 未终止,则它的所有进程 ID 都将被终止。
    【解决方案4】:

    如果你有 killall:

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

    或者:

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

    【讨论】:

    • 还有pkill,虽然我认为我是世界上唯一使用它而不是killall的人
    • 好吧,是的,看起来第一个命令运行良好。感谢您的帮助。
    • @MichaelMrozek 你怎么能忍受像killall java这样的输入的甜蜜感觉?
    • @Michael 我使用pkill,因为我知道的唯一killall 是“杀死一切”。
    【解决方案5】:

    这在 Windows 7 中对我有用

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

    【讨论】:

      【解决方案6】:

      你可以试试这个。 但在您需要使用sudo pip install psutil 安装psutil 之前

      import psutil
      for proc in psutil.process_iter(attrs=['pid', 'name']):
          if 'ichat' in proc.info['name']:
              proc.kill()
      

      【讨论】:

      • 至少这是可移植的,即使接受的答案已经描述了这个解决方案。
      【解决方案7】:

      以下代码将杀死所有面向 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)
      

      【讨论】:

        【解决方案8】:

        使用Process获取进程对象。

        >>> import psutil
        >>> p = psutil.Process(23442)
        >>> p
        psutil.Process(pid=23442, name='python3.6', started='09:24:16')
        >>> p.kill()
        >>> 
        

        【讨论】:

          【解决方案9】:

          您可以使用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à 的answer

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

          我还将这个 sn-p 发布为 gist

          注意:一旦您对观察到所需行为感到满意,您可以删除打印语句。

          【讨论】:

            【解决方案10】:

            您可以在 Windows 上使用 WMI 模块来执行此操作,尽管它比 unix 人习惯的要笨重得多; import WMI 需要很长时间,而且过程中会有中间的痛苦。

            【讨论】:

              【解决方案11】:

              如果你想杀死带有特定标题的进程或 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 ) 
              

              希望对您有所帮助。他们可能是我的许多更好的解决方案。

              【讨论】:

                【解决方案12】:

                Alex Martelli 的答案在 Python 3 中不起作用,因为 out 将是一个字节对象,因此在测试 if 'iChat' in line: 时会产生 TypeError: a bytes-like object is required, not 'str'

                引用子进程documentation:

                communicate() 返回一个元组 (stdout_data, stderr_data)。如果流以文本模式打开,则数据将是字符串;否则,字节。

                对于 Python 3,通过将 text=True (>= Python 3.7) 或 universal_newlines=True 参数添加到 Popen 构造函数来解决此问题。 out 然后将作为字符串对象返回。

                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)
                

                或者,您可以使用字节的 decode() 方法创建一个字符串。

                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)
                

                【讨论】:

                  【解决方案13】:

                  与 Giampaolo Rodolà 的回答风格相同,但作为一个衬线,不区分大小写且不必匹配整个进程名称,在 Windows 中,您必须包含 .exe 后缀。

                  [x.kill() for x in psutil.process_iter() if 'ichat' in x.name().lower()]
                  

                  【讨论】:

                    【解决方案14】:

                    您可以在 unix 系统中使用pkill <process_name> 按名称杀死进程。

                    那么python代码将是:

                    >>> import os
                    >>> process_name=iChat
                    >>> os.system('pkill '+process_name)
                    

                    【讨论】:

                    • 我使用的所有系统都是 Mac,当我尝试运行 pkill 时,它只是告诉我找不到该命令。
                    【解决方案15】:

                    对我来说唯一有效的是:

                    例如

                    import subprocess
                    proc = subprocess.Popen(["pkill", "-f", "scriptName.py"], stdout=subprocess.PIPE)
                    proc.wait()
                    

                    【讨论】:

                      【解决方案16】:
                      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)
                      

                      【讨论】:

                        【解决方案17】:
                        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()
                        

                        【讨论】:

                          猜你喜欢
                          • 2011-06-19
                          • 1970-01-01
                          • 2017-10-02
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-01-21
                          • 2018-02-28
                          • 1970-01-01
                          相关资源
                          最近更新 更多