2009-02-15 9 views
45

Varios procesos con el mismo nombre se están ejecutando en el host. ¿Cuál es la forma de plataforma cruzada para obtener los PID de esos procesos por nombre usando python o jython?Forma de plataforma cruzada para obtener PID por nombre de proceso en python

  1. Quiero algo como pidof pero en python. (No tengo pidof de todos modos.)
  2. No puedo analizar /proc porque podría no estar disponible (en HP-UX).
  3. No quiero ejecutar os.popen('ps') y analizar el resultado porque creo que es feo (la secuencia de campo puede ser diferente en diferentes sistemas operativos).
  4. Las plataformas de destino son Solaris, HP-UX y tal vez otras.

Respuesta

61

Puede utilizar psutil (https://github.com/giampaolo/psutil), que funciona en Windows y UNIX:

import psutil 

PROCNAME = "python.exe" 

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

En mi máquina imprime:

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

EDITAR 27/04/2017 - he aquí una función de utilidad más avanzada que comprueba el nombre en nombre de procesos(), cmdline() y 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 
+0

HAS hizo módulo muy útil. Gracias. –

+0

Pocos clics y he terminado (incluso en Windows). Estupendo. –

+1

Desafortunadamente, OS X no le permite acceder a muchos atributos de un proceso (nombre, exe, línea de cmd), incluso si solo intenta acceder a los procesos creados por usted. A menos que ejecute el intérprete/script con sudo, eso es. – John

3

No creo que pueda encontrar una solución portátil puramente basada en Python sin usar las utilidades de/proc o línea de comandos, al menos no en Python. Analizar os.system no es feo: alguien tiene que lidiar con múltiples plataformas, ya sea usted u otra persona. Implementarlo para el sistema operativo que le interesa debería ser bastante fácil, honestamente.

3

Primero, Windows (en todas sus encarnaciones) es un sistema operativo no estándar.

Linux (y el unixen más exclusivo) son sistemas operativos estándar que cumplen con POSIX.

Las bibliotecas C reflejan esta dicotomía. Python refleja las bibliotecas de C.

No existe una forma de "plataforma cruzada" para hacer esto. Tienes que hackear algo con ctypes para una versión particular de Windows (XP o Vista)

+0

un ejemplo sería bienvenido, así como enlaces a los documentos – n611x007

1

No hay, me temo. Los procesos se identifican de manera única por pid, no por nombre. Si realmente debe encontrar un pid por su nombre, entonces tendrá que usar algo como lo que ha sugerido, pero no será portátil y probablemente no funcione en todos los casos.

Si solo tiene que encontrar las pides para una aplicación determinada y tiene control sobre esta aplicación, le sugiero que cambie esta aplicación para almacenar su pid en archivos en alguna ubicación donde su script pueda encontrarlo.

1

Para jython, si se utiliza Java 5, entonces se puede obtener el identificador de proceso de Java de la siguiente manera:

de importación java.lang.management *
pid = ManagementFactory.getRuntimeMXBean() getName()

.
+0

que funciona, pero quiero obtener PID de otro proceso (como pidof do, pero sin usar pidof) –

11

No hay una única API multiplataforma, deberá verificar el sistema operativo. Para uso basado en posix/proc. Para el uso de Windows siguiente código para obtener la lista de todos los PID con coresponding nombres de los procesos

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] 

A continuación, puede filtrar fácilmente los procesos que necesita. Para obtener más información sobre las propiedades disponibles de Win32_Process echa un vistazo a Win32_Process Class

+0

Esta biblioteca no viene de serie con Python, al menos no con 2.7. No revisé las otras versiones. –

+1

@ZoranPavlovic sí y es el paquete 'pywin32' con http://sourceforge.net/projects/pywin32/files/pywin32/ construye la respuesta debería haber incluido este – n611x007

7
import psutil 

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

dar a todos los PIDs de "YourProcess.exe"

+1

No tengo ninguna apuesta de ninguna manera; A menudo escucho a la gente decir que Comprensión de lista es * siempre * la mejor manera de filtrar una lista porque es más rápida. por ejemplo 'process = [proc for proc in psutil.process_iter() if proc.name ==" YourProcess.exe "]'. – ThorSummoner

0

Una nota sobre ThorSummoner's comment

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

Lo he probado en Debian con Python 3, creo que tiene que ser proc.name() vez de proc.name.

Cuestiones relacionadas