【问题标题】:How do you get the process ID of a program in Unix or Linux using Python?如何使用 Python 获取 Unix 或 Linux 中程序的进程 ID?
【发布时间】:2011-04-15 06:26:07
【问题描述】:

我正在用 Python 编写一些监控脚本,并试图找到最简洁的方法来获取给定程序名称的任何随机运行程序的进程 ID

类似

ps -ef | grep MyProgram

我可以解析它的输出,但是我认为在 python 中可能有更好的方法

【问题讨论】:

  • 如果你想跨平台工作(例如在 Linux、Mac、Solaris 上也一样),没有比解析pf 输出更好的方法了。如果它是针对一个非常特定的平台,请编辑您的 Q 以添加显然至关重要的信息(您需要定位的确切操作系统版本)标签!
  • 可以直接在python中解析ps的输出

标签: python


【解决方案1】:

【讨论】:

  • 得到的不是用户要求的python进程的pid
  • 是的,它让我得到了我来这里的目的。
【解决方案2】:

如果您不局限于标准库,我喜欢psutil

例如查找所有“python”进程:

>>> import psutil
>>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']]
[{'name': 'python3', 'pid': 21947},
 {'name': 'python', 'pid': 23835}]

【讨论】:

  • 你能否提供一个相同的例子。
  • 因为缺乏例子
【解决方案3】:

试试pgrep。它的输出格式更简单,因此更容易解析。

【讨论】:

    【解决方案4】:

    对于 Windows

    一种无需下载任何模块即可获取计算机上所有程序 pid 的方法:

    import os
    
    pids = []
    a = os.popen("tasklist").readlines()
    for x in a:
          try:
             pids.append(int(x[29:34]))
          except:
               pass
    for each in pids:
             print(each)
    

    如果您只想要一个程序或所有程序具有相同名称并且想要终止进程或其他东西:

    import os, sys, win32api
    
    tasklistrl = os.popen("tasklist").readlines()
    tasklistr = os.popen("tasklist").read()
    
    print(tasklistr)
    
    def kill(process):
         process_exists_forsure = False
         gotpid = False
         for examine in tasklistrl:
                if process == examine[0:len(process)]:
                    process_exists_forsure = True
         if process_exists_forsure:
             print("That process exists.")
         else:
            print("That process does not exist.")
            raw_input()
            sys.exit()
         for getpid in tasklistrl:
             if process == getpid[0:len(process)]:
                    pid = int(getpid[29:34])
                    gotpid = True
                    try:
                      handle = win32api.OpenProcess(1, False, pid)
                      win32api.TerminateProcess(handle, 0)
                      win32api.CloseHandle(handle)
                      print("Successfully killed process %s on pid %d." % (getpid[0:len(prompt)], pid))
                    except win32api.error as err:
                      print(err)
                      raw_input()
                      sys.exit()
        if not gotpid:
           print("Could not get process pid.")
           raw_input()
           sys.exit()
    
       raw_input()
       sys.exit()
    
    prompt = raw_input("Which process would you like to kill? ")
    kill(prompt)
    

    这只是我的进程终止程序的粘贴,我可以让它变得更好,但没关系。

    【讨论】:

      【解决方案5】:

      可以使用以下代码解决该任务,[0:28] 是保存名称的间隔,而 [29:34] 包含实际的 pid。

      import os
      
      program_pid = 0
      program_name = "notepad.exe"
      
      task_manager_lines = os.popen("tasklist").readlines()
      for line in task_manager_lines:
          try:
              if str(line[0:28]) == program_name + (28 - len(program_name) * ' ': #so it includes the whitespaces
                  program_pid = int(line[29:34])
                  break
          except:
              pass
      
      print(program_pid)
      

      【讨论】:

        【解决方案6】:

        还有: Python: How to get PID by process name?

        适应以前发布的答案。

        def getpid(process_name):
            import os
            return [item.split()[1] for item in os.popen('tasklist').read().splitlines()[4:] if process_name in item.split()]
        
        getpid('cmd.exe')
        ['6560', '3244', '9024', '4828']
        

        【讨论】:

          【解决方案7】:

          对于 posix(Linux、BSD 等...只需要挂载 /proc 目录),使用 /proc 中的 os 文件更容易

          适用于 python 2 和 3(唯一的区别是异常树,因此是“except Exception”,我不喜欢但保持兼容性。也可以创建自定义异常。)

          #!/usr/bin/env python
          
          import os
          import sys
          
          
          for dirname in os.listdir('/proc'):
              if dirname == 'curproc':
                  continue
          
              try:
                  with open('/proc/{}/cmdline'.format(dirname), mode='rb') as fd:
                      content = fd.read().decode().split('\x00')
              except Exception:
                  continue
          
              for i in sys.argv[1:]:
                  if i in content[0]:
                      # dirname is also the number of PID
                      print('{0:<12} : {1}'.format(dirname, ' '.join(content)))
          

          示例输出(它的工作方式类似于 pgrep):

          phoemur ~/python $ ./pgrep.py bash
          1487         : -bash 
          1779         : /bin/bash
          

          【讨论】:

            【解决方案8】:

            psutil:

            (可以用[sudo] pip install psutil安装)

            import psutil
            
            # Get current process pid
            current_process_pid = psutil.Process().pid
            print(current_process_pid)  # e.g 12971
            
            # Get pids by program name
            program_name = 'chrome'
            process_pids = [process.pid for process in psutil.process_iter() if process.name == program_name]
            print(process_pids)  # e.g [1059, 2343, ..., ..., 9645]
            

            【讨论】:

            • 对于那些试图使用这个例子,但意识到它总是导致一个空列表的人。将if process.name 更改为if process.name()
            【解决方案9】:

            这是费尔南多答案的简化变体。这适用于 Linux 和 Python 2 或 3。不需要外部库,也不需要运行外部进程。

            import glob
            
            def get_command_pid(command):
                for path in glob.glob('/proc/*/comm'):
                    if open(path).read().rstrip() == command:
                        return path.split('/')[2]
            

            只会返回找到的第一个匹配进程,这对于某些用途非常有效。要获取多个匹配进程的 PID,只需将 return 替换为 yield,然后使用 pids = list(get_command_pid(command)) 获取列表即可。

            或者,作为单个表达式:

            对于一个进程:

            next(path.split('/')[2] for path in glob.glob('/proc/*/comm') if open(path).read().rstrip() == command)
            

            对于多个进程:

            [path.split('/')[2] for path in glob.glob('/proc/*/comm') if open(path).read().rstrip() == command]
            

            【讨论】:

              猜你喜欢
              • 2014-06-29
              • 2010-10-11
              • 2020-08-10
              • 1970-01-01
              • 2011-04-20
              • 2014-11-02
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多