webentwicklung-frage-antwort-db.com.de

Plattformübergreifende Möglichkeit, PIDs nach Prozessnamen in Python abzurufen

Auf dem Host werden mehrere Prozesse mit demselben Namen ausgeführt. Wie können plattformübergreifend PIDs dieser Prozesse über python oder jython abgerufen werden?

  1. Ich möchte etwas wie pidof aber in Python. (Ich habe sowieso nicht pidof.)
  2. Ich kann /proc nicht analysieren, da er möglicherweise nicht verfügbar ist (unter HP-UX).
  3. Ich möchte os.popen('ps') nicht ausführen und die Ausgabe parsen, weil ich es für hässlich halte (die Reihenfolge der Felder kann sich in verschiedenen Betriebssystemen unterscheiden).
  4. Zielplattformen sind Solaris, HP-UX und möglicherweise andere.
49
Alex Bolotov

Sie können psutil ( https://github.com/giampaolo/psutil ) verwenden, das unter Windows und UNIX funktioniert:

import psutil

PROCNAME = "python.exe"

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

Auf meiner Maschine druckt es:

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

EDIT 2017-04-27 - Hier ist eine erweiterte Utility-Funktion, die den Namen gegen den Namen (), Cmdline () und Exe () der Prozesse überprüft:

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
69

Es gibt keine einzige plattformübergreifende API. Sie müssen das Betriebssystem überprüfen. Für posix-basierte Verwendung/proc. Verwenden Sie für Windows folgenden Code, um eine Liste aller Pids mit entsprechenden Prozessnamen abzurufen

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]

Sie können dann die Prozesse, die Sie benötigen, einfach herausfiltern. Für weitere Informationen zu den verfügbaren Eigenschaften von Win32_Process checkout Win32_Process Class

11
Ivan
import psutil

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

Geben Sie alle Optionen von "YourProcess.exe"

9
baco

Erstens ist Windows (in allen seinen Inkarnationen) ein nicht standardmäßiges Betriebssystem.

Linux (und die meisten proprietären Unixen) sind POSIX-kompatible Standardbetriebssysteme.

Die C-Bibliotheken spiegeln diese Dichotomie wider. Python spiegelt die C-Bibliotheken wider.

Es gibt keinen "plattformübergreifenden" Weg, dies zu tun. Sie müssen etwas mit ctypes für eine bestimmte Version von Windows (XP oder Vista) hacken.

4
S.Lott

Ich glaube nicht, dass Sie eine rein pythonbasierte, portable Lösung finden können, ohne/proc oder Befehlszeilen-Dienstprogramme zu verwenden, zumindest nicht in Python selbst. Das Analysieren von os.system ist nicht hässlich - jemand muss sich mit den verschiedenen Plattformen befassen, sei es Sie oder jemand anderes. Die Implementierung für das Betriebssystem, an dem Sie interessiert sind, sollte recht einfach und ehrlich sein.

3

Eine Anmerkung zu ThorSummoners Kommentar

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

Ich habe es auf Debian mit Python 3 ausprobiert, ich denke es muss proc.name() anstelle von proc.name sein.

1
pchaitat

Ich habe keine Angst. Prozesse werden eindeutig durch pid identifiziert, nicht durch Namen. Wenn Sie wirklich eine PID anhand des Namens finden müssen, müssen Sie etwas verwenden, das Sie vorgeschlagen haben, aber es wird nicht portabel sein und funktioniert wahrscheinlich nicht in allen Fällen.

Wenn Sie nur die PIDs für eine bestimmte Anwendung suchen müssen und Sie die Kontrolle über diese Anwendung haben, würde ich vorschlagen, diese App so zu ändern, dass die PIDs in Dateien an einem Ort gespeichert werden, wo Ihr Skript sie finden kann.

1
ubiyubix

Bei Jython können Sie, wenn Java 5 verwendet wird, die Java-Prozess-ID wie folgt abrufen:

aus Java.lang.management import *
pid = ManagementFactory.getRuntimeMXBean (). getName ()

1
ccyu