tutorial - ¿Cómo se obtiene el ID de proceso de un programa en Unix o Linux usando Python?
python ppt español (9)
Estoy escribiendo algunos scripts de monitoreo en Python y estoy tratando de encontrar la manera más limpia de obtener el ID de proceso de cualquier programa aleatorio dado el nombre de ese programa
algo como
ps -ef | grep MyProgram
Podría analizar la salida de eso, sin embargo, pensé que podría haber una mejor manera en Python
Con psutil
:
(Se puede instalar con [sudo] pip install psutil
)
import psutil
# Get current process pid
current_process_pid = psutil.Process().pid
print(current_process_pid) # e.g 12971
# Get pids by program name
program_name = ''chrome''
process_pids = [process.pid for process in psutil.process_iter() if process.name == program_name]
print(process_pids) # e.g [1059, 2343, ..., ..., 9645]
Esta es una variación simplificada de la respuesta de Fernando. Esto es para Linux y Python 2 o 3. No se necesita una biblioteca externa, y no se ejecuta ningún proceso externo.
import glob
def get_command_pid(command):
for path in glob.glob(''/proc/*/comm''):
if open(path).read().rstrip() == command:
return path.split(''/'')[2]
Solo se devolverá el primer proceso de coincidencia encontrado, que funciona bien para algunos propósitos. Para obtener los PID de varios procesos coincidentes, simplemente puede reemplazar el return
con el yield
y luego obtener una lista con pids = list(get_command_pid(command))
.
Alternativamente, como una sola expresión:
Para un proceso:
next(path.split(''/'')[2] for path in glob.glob(''/proc/*/comm'') if open(path).read().rstrip() == command)
Para procesos múltiples:
[path.split(''/'')[2] for path in glob.glob(''/proc/*/comm'') if open(path).read().rstrip() == command]
La tarea se puede resolver utilizando el siguiente fragmento de código, siendo [0:28] el intervalo donde se guarda el nombre, mientras que [29:34] contiene el pid real.
import os
program_pid = 0
program_name = "notepad.exe"
task_manager_lines = os.popen("tasklist").readlines()
for line in task_manager_lines:
try:
if str(line[0:28]) == program_name + (28 - len(program_name) * '' '': #so it includes the whitespaces
program_pid = int(line[29:34])
break
except:
pass
print(program_pid)
Para posix (Linux, BSD, etc ... solo es necesario montar el directorio / proc) es más fácil trabajar con archivos OS en / proc
Funciona en Python 2 y 3 (la única diferencia es el árbol de Excepciones, por lo tanto, la " excepción de excepción ", que no me gusta pero se mantuvo para mantener la compatibilidad. También podría haber creado una excepción personalizada)
#!/usr/bin/env python
import os
import sys
for dirname in os.listdir(''/proc''):
if dirname == ''curproc'':
continue
try:
with open(''/proc/{}/cmdline''.format(dirname), mode=''rb'') as fd:
content = fd.read().decode().split(''/x00'')
except Exception:
continue
for i in sys.argv[1:]:
if i in content[0]:
# dirname is also the number of PID
print(''{0:<12} : {1}''.format(dirname, '' ''.join(content)))
Salida de muestra (funciona como pgrep):
phoemur ~/python $ ./pgrep.py bash
1487 : -bash
1779 : /bin/bash
Para ventanas
Una forma de obtener todos los pids de programas en su computadora sin descargar ningún módulo:
import os
pids = []
a = os.popen("tasklist").readlines()
for x in a:
try:
pids.append(int(x[29:34]))
except:
pass
for each in pids:
print(each)
Si solo quería un programa o todos los programas con el mismo nombre y deseaba detener el proceso o algo así:
import os, sys, win32api
tasklistrl = os.popen("tasklist").readlines()
tasklistr = os.popen("tasklist").read()
print(tasklistr)
def kill(process):
process_exists_forsure = False
gotpid = False
for examine in tasklistrl:
if process == examine[0:len(process)]:
process_exists_forsure = True
if process_exists_forsure:
print("That process exists.")
else:
print("That process does not exist.")
raw_input()
sys.exit()
for getpid in tasklistrl:
if process == getpid[0:len(process)]:
pid = int(getpid[29:34])
gotpid = True
try:
handle = win32api.OpenProcess(1, False, pid)
win32api.TerminateProcess(handle, 0)
win32api.CloseHandle(handle)
print("Successfully killed process %s on pid %d." % (getpid[0:len(prompt)], pid))
except win32api.error as err:
print(err)
raw_input()
sys.exit()
if not gotpid:
print("Could not get process pid.")
raw_input()
sys.exit()
raw_input()
sys.exit()
prompt = raw_input("Which process would you like to kill? ")
kill(prompt)
Eso fue solo una pasta de mi programa de eliminación de procesos. Podría hacerlo mucho mejor, pero está bien.
Pruebe pgrep
. Su formato de salida es mucho más simple y, por lo tanto, más fácil de analizar.
Si no te estás limitando a la biblioteca estándar, me gusta psutil para esto.
Por ejemplo, para encontrar todos los procesos "python":
>>> import psutil
>>> [p.info for p in psutil.process_iter(attrs=[''pid'', ''name'']) if ''python'' in p.info[''name'']]
[{''name'': ''python3'', ''pid'': 21947},
{''name'': ''python'', ''pid'': 23835}]
También: Python: ¿Cómo obtener PID por nombre de proceso?
Adaptación a las respuestas anteriores publicadas.
def getpid(process_name):
import os
return [item.split()[1] for item in os.popen(''tasklist'').read().splitlines()[4:] if process_name in item.split()]
getpid(''cmd.exe'')
[''6560'', ''3244'', ''9024'', ''4828'']
os.getpid()