web-dev-qa-db-fra.com

Méthode multiplateforme pour obtenir les PID par nom de processus en python

Plusieurs processus portant le même nom s'exécutent sur l'hôte. Quel est le moyen multiplateforme d'obtenir les PID de ces processus en utilisant python ou jython ?

  1. Je veux quelque chose comme pidof mais en python. (Je n'ai pas pidof de toute façon.)
  2. Je ne peux pas analyser /proc car il est possible qu'il ne soit pas disponible (sous HP-UX).
  3. Je ne veux pas exécuter os.popen('ps') et analyser la sortie car je pense que c'est moche (la séquence de champs peut être différente dans différents systèmes d'exploitation).
  4. Les plates-formes cibles sont Solaris, HP-UX et peut-être d'autres.
49
Alex Bolotov

Vous pouvez utiliser psutil ( https://github.com/giampaolo/psutil ), qui fonctionne sous Windows et UNIX:

import psutil

PROCNAME = "python.exe"

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

Sur ma machine, il imprime:

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

EDIT 2017-04-27 - voici une fonction utilitaire plus avancée qui compare le nom aux processus name (), cmdline () et 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
69
Giampaolo Rodolà

Il n'y a pas d'API multiplate-forme unique, vous devrez vérifier le système d'exploitation. Pour une utilisation basée sur posix/proc. Pour Windows, utilisez le code suivant pour obtenir la liste de toutes les PID avec les noms de processus correspondants

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]

Vous pouvez alors facilement filtrer les processus dont vous avez besoin . Pour plus d'informations sur les propriétés disponibles de Win32_Process, consultez Classe Win32_Process

11
Ivan
import psutil

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

Donnez tous les pids de "YourProcess.exe"

9
baco

Premièrement, Windows (dans toutes ses incarnations) est un système d'exploitation non standard.

Linux (et la plupart des systèmes Unix propriétaires) sont des systèmes d'exploitation standard compatibles POSIX.

Les bibliothèques C reflètent cette dichotomie. Python reflète les bibliothèques C.

Il n'y a pas de moyen "multi-plateforme" pour le faire. Vous devez pirater quelque chose avec ctypes pour une version particulière de Windows (XP ou Vista)

4
S.Lott

Je ne pense pas que vous puissiez trouver une solution portable entièrement basée sur python sans utiliser/proc ou des utilitaires de ligne de commande, du moins pas en python lui-même. L'analyse de os.system n'est pas moche - quelqu'un doit faire face à de multiples plateformes, que ce soit vous ou quelqu'un d'autre. La mise en œuvre pour le système d'exploitation qui vous intéresse devrait être assez facile, honnêtement.

3
David Cournapeau

Une note sur le commentaire de ThorSummoner

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

Je l'ai essayé sur Debian avec Python 3, je pense que ça doit être proc.name() au lieu de proc.name.

1
pchaitat

Il n'y en a pas, j'ai bien peur. Les processus sont uniquement identifiés par pid et non par nom. Si vous devez vraiment trouver un pid par son nom, vous utiliserez quelque chose que vous avez suggéré, mais il ne sera pas portable et ne fonctionnera probablement pas dans tous les cas.

Si vous devez seulement trouver les pids pour une application donnée et que vous avez le contrôle de cette application, alors je vous suggère de changer cette application pour stocker son pid dans des fichiers situés à un emplacement où votre script pourra le trouver.

1
ubiyubix

Pour Jython, si Java 5 est utilisé, vous pouvez obtenir l'ID de processus Java comme suit:

à partir de Java.lang.management import *
pid = ManagementFactory.getRuntimeMXBean (). getName ()

1
ccyu