Подтвердить что ты не робот

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

На хосте выполняется несколько процессов с тем же именем. Что такое кросс-платформенный способ получения PID этих процессов по имени с помощью python или jython?

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

Ответ 1

Вы можете использовать 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>

EDIT 2017-04-27 - здесь представлена ​​более продвинутая функция полезности, которая проверяет имя на имя процессов(), 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

Ответ 2

Нет единого межплатформенного 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

Ответ 3

import psutil

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

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

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

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

Ответ 7

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

из java.lang.management import *
pid = ManagementFactory.getRuntimeMXBean(). getName()

Ответ 8

Заметка Комментарий ThorSummoner

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

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