Кроссплатформенный способ получить PID по имени процесса в Python

StackOverflow https://stackoverflow.com/questions/550653

Вопрос

На хосте запущено несколько процессов с одинаковым именем.Каков кросс-платформенный способ получить PID этих процессов по имени, используя питон или Джитон?

  1. Я хочу что-то вроде pidof но на питоне.(у меня нет pidof в любом случае.)
  2. я не могу разобрать /proc поскольку он может быть недоступен (в HP-UX).
  3. я не хочу бежать os.popen('ps') и проанализировать вывод, потому что я считаю его некрасивым (последовательность полей может отличаться в разных ОС).
  4. Целевые платформы — Solaris, HP-UX и, возможно, другие.
Это было полезно?

Решение

Вы можете использовать psutil (https://github.com/giampaolo/psutil), который работает в Windows и UNIX:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    if proc.name() == PROCNAME:
        print(proc)

На моей машине печатается:

<psutil.Process(pid=3881, name='python.exe') at 140192133873040>

РЕДАКТИРОВАТЬ 27 апреля 2017 г. - вот более продвинутая служебная функция, которая проверяет имя по имени процесса(), cmdline() и exe():

import os
import psutil

def find_procs_by_name(name):
    "Return a list of processes matching 'name'."
    assert name, name
    ls = []
    for p in psutil.process_iter():
        name_, exe, cmdline = "", "", []
        try:
            name_ = p.name()
            cmdline = p.cmdline()
            exe = p.exe()
        except (psutil.AccessDenied, psutil.ZombieProcess):
            pass
        except psutil.NoSuchProcess:
            continue
        if name == name_ or cmdline[0] == name or os.path.basename(exe) == name:
            ls.append(name)
    return ls

Другие советы

Единого кроссплатформенного API не существует, вам придется проверять ОС.Для использования posix используйте /proc.Для Windows используйте следующий код, чтобы получить список всех PID с соответствующими именами процессов.

from win32com.client import GetObject
WMI = GetObject('winmgmts:')
processes = WMI.InstancesOf('Win32_Process')
process_list = [(p.Properties_("ProcessID").Value, p.Properties_("Name").Value) for p in processes]

Затем вы можете легко отфильтровать нужные вам процессы.Дополнительную информацию о доступных свойствах Win32_Process см. Класс Win32_Process

import psutil

process = filter(lambda p: p.name() == "YourProcess.exe", psutil.process_iter())
for i in process:
  print i.name,i.pid

Дайте все PID "YourProcess.exe"

Во-первых, Windows (во всех своих воплощениях) — нестандартная ОС.

Linux (и большинство проприетарных Unixen) являются стандартными операционными системами, совместимыми с POSIX.

Библиотеки C отражают эту дихотомию.Python отражает библиотеки C.

Не существует «кросс-платформенного» способа сделать это.Вам нужно что-то взломать с помощью cтипы для конкретной версии Windows (XP или Vista)

Я не думаю, что вы сможете найти переносимое решение, полностью основанное на Python, без использования /proc или утилит командной строки, по крайней мере, не в самом Python.Анализ os.system не уродлив — кому-то приходится иметь дело с несколькими платформами, будь то вы или кто-то другой.Честно говоря, реализовать его для интересующей вас ОС должно быть довольно легко.

Боюсь, нет.Процессы однозначно идентифицируются по pid, а не по имени.Если вам действительно необходимо найти pid по имени, вам придется использовать что-то вроде того, что вы предложили, но оно не будет переносимым и, вероятно, не будет работать во всех случаях.

Если вам нужно найти pid-коды только для определенного приложения и вы можете контролировать это приложение, я бы предложил изменить это приложение так, чтобы его pid-код хранился в файлах в каком-то месте, где ваш скрипт сможет его найти.

Для jython, если используется Java 5, вы можете получить идентификатор процесса Java следующим образом:

из импорта java.lang.management *
pid = ManagementFactory.getRuntimeMXBean().getName()

Примечание о Комментарий ThorSummoner

process = [proc for proc in psutil.process_iter() if proc.name == "YourProcess.exe"].

Я пробовал это на Debian с Python 3, думаю, так и должно быть. proc.name() вместо proc.name.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top