Wieloplatformowy sposób uzyskiwania PID przez nazwę procesu w Pythonie

Kilka procesów o tej samej nazwie jest uruchomionych na komputerze. Jaki jest wieloplatformowy sposób na uzyskanie PID tych procesów według nazwy za pomocą pythonlub jython?

  1. chcę coś w stylu pidof ale w Pythonie. (I tak nie mam pidof.)
  2. nie mogę analizować /proc, ponieważ może być niedostępny (na HP-UX).
  3. nie chcę uruchamiać os.popen('ps') i analizować wyjścia, ponieważ uważam, że jest brzydkie (kolejność pól może być inna w różnych OS).
  4. [11]}docelowymi platformami są Solaris, HP-UX i być może inne.
Author: Julien, 2009-02-15

8 answers

Możesz użyć psutil ( https://github.com/giampaolo/psutil ), który działa na systemach Windows i UNIX:

import psutil

PROCNAME = "python.exe"

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

Na mojej maszynie drukuje:

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

Edycja 2017-04-27-oto bardziej zaawansowana funkcja narzędzia, która sprawdza nazwę pod względem nazw procesów (), cmdline () i 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
 65
Author: Giampaolo Rodolà,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-27 02:35:34

Nie ma jednego wieloplatformowego API, musisz sprawdzić system operacyjny. Do użytku opartego na posix /proc. Dla systemu Windows użyj poniższego kodu, aby uzyskać listę wszystkich PID z nazwami procesów rdzeniowych

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]

Możesz następnie łatwo odfiltrować procesy, których potrzebujesz. Aby uzyskać więcej informacji na temat dostępnych właściwości Win32_Process sprawdź Win32_Process Class

 11
Author: Ivan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-04 10:00:18
import psutil

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

Give all pids of " YourProcess.exe "

 8
Author: baco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-21 22:05:11

Myślę, że nie uda Ci się znaleźć czysto pythonowego, przenośnego rozwiązania bez użycia /proc lub narzędzi wiersza poleceń, przynajmniej nie w samym Pythonie. Parsowanie os.system nie jest brzydki-ktoś musi radzić sobie z wieloma platformami, czy to Ty, Czy ktoś inny. Wdrożenie go dla systemu operacyjnego, który Cię interesuje, powinno być dość łatwe, uczciwie.

 3
Author: David Cournapeau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 10:35:56

Po pierwsze, Windows (we wszystkich jego wcieleniach) jest niestandardowym systemem operacyjnym.

Linux (i większość zastrzeżonych unixen) są standardowymi systemami operacyjnymi zgodnymi ze standardem POSIX.

Biblioteki C odzwierciedlają tę dychotomię. Python odzwierciedla biblioteki C.

Nie ma na to "wieloplatformowego" sposobu. Musisz zhakować coś z ctypes dla konkretnej wersji Windows (XP lub Vista)

 3
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 12:43:05

Obawiam się, że nie ma. Procesy są jednoznacznie identyfikowane przez pid, a nie przez nazwę. Jeśli naprawdę musisz znaleźć pid po nazwie, będziesz musiał użyć czegoś takiego, jak zasugerowałeś, ale nie będzie to przenośne i prawdopodobnie nie będzie działać we wszystkich przypadkach.

Jeśli musisz tylko znaleźć PID dla określonej aplikacji i masz kontrolę nad tą aplikacją, sugerowałbym zmianę tej aplikacji, aby przechowywała swój pid w plikach w jakimś miejscu, gdzie skrypt może go znaleźć.

 1
Author: ubiyubix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-17 14:21:30

Dla jython, jeśli używana jest Java 5, to można uzyskać ID procesu Java w następujący sposób:

Z Javy.lang.zarządzanie importem *
pid = ManagementFactory.getRuntimeMXBean().getName ()

 1
Author: ccyu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-07 18:30:37

Uwaga na komentarz Thorsummonera

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

Próbowałem go na Debianie z Pythonem 3, myślę, że to musi być proc.name() zamiast proc.name.

 0
Author: pchaitat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:48