Como você verifica no Linux com Python se um processo ainda está em execução?[duplicado]
Pergunta
Essa pergunta já tem resposta aqui:
A única legal maneira que encontrei é:
import sys
import os
try:
os.kill(int(sys.argv[1]), 0)
print "Running"
except:
print "Not running"
(Fonte)
Mas isso é confiável?Funciona com todos os processos e todas as distribuições?
Solução
Afinal, a resposta de Mark é o caminho a seguir, é por isso que o sistema de arquivos /proc existe.Para algo um pouco mais copiável/colável:
>>> import os.path
>>> os.path.exists("/proc/0")
False
>>> os.path.exists("/proc/12")
True
Outras dicas
no Linux, você pode procurar no diretório /proc/$PID para obter informações sobre esse processo.Na verdade, se o diretório existir, o processo está em execução.
Deve funcionar em qualquer sistema POSIX (embora olhando para o /proc
sistema de arquivos, como outros sugeriram, é mais fácil se você sabe que estará lá).
No entanto: os.kill
também poderá falhar se você não tiver permissão para sinalizar o processo.Você precisaria fazer algo como:
import sys
import os
import errno
try:
os.kill(int(sys.argv[1]), 0)
except OSError, err:
if err.errno == errno.ESRCH:
print "Not running"
elif err.errno == errno.EPERM:
print "No permission to signal this process!"
else:
print "Unknown error"
else:
print "Running"
Aqui está a solução que resolveu isso para mim:
import os
import subprocess
import re
def findThisProcess( process_name ):
ps = subprocess.Popen("ps -eaf | grep "+process_name, shell=True, stdout=subprocess.PIPE)
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
return output
# This is the function you can use
def isThisRunning( process_name ):
output = findThisProcess( process_name )
if re.search('path/of/process'+process_name, output) is None:
return False
else:
return True
# Example of how to use
if isThisRunning('some_process') == False:
print("Not running")
else:
print("Running!")
Sou um novato em Python + Linux, então isso pode não ser o ideal.Resolveu meu problema e espero que ajude outras pessoas também.
// Mas isso é confiável?Funciona com todos os processos e todas as distribuições?
Sim, deve funcionar em qualquer distribuição Linux.Esteja ciente de que /proc não está facilmente disponível em sistemas baseados em Unix (FreeBSD, OSX).
Parece-me que uma solução baseada em PID é muito vulnerável.Se o processo cujo status você está tentando verificar foi encerrado, seu PID poderá ser reutilizado por um novo processo.Então, IMO ShaChris23, o novato em Python + Linux, deu a melhor solução para o problema.Mesmo que só funcione se o processo em questão for identificável exclusivamente por sua sequência de comandos, ou se você tiver certeza de que haverá apenas um em execução por vez.
Eu uso isso para obter os processos e a contagem do processo com o nome especificado
import os
processname = 'somprocessname'
tmp = os.popen("ps -Af").read()
proccount = tmp.count(processname)
if proccount > 0:
print(proccount, ' processes running of ', processname, 'type')
Eu tive problemas com as versões acima (por exemplo, a função encontrada também parte da string e tais coisas ...), então escrevi minha própria versão modificada do Maksym Kozlenko's:
#proc -> name/id of the process
#id = 1 -> search for pid
#id = 0 -> search for name (default)
def process_exists(proc, id = 0):
ps = subprocess.Popen("ps -A", shell=True, stdout=subprocess.PIPE)
ps_pid = ps.pid
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
for line in output.split("\n"):
if line != "" and line != None:
fields = line.split()
pid = fields[0]
pname = fields[3]
if(id == 0):
if(pname == proc):
return True
else:
if(pid == proc):
return True
return False
Acho que é mais confiável, mais fácil de ler e você tem a opção de verificar ids ou nomes de processos.
Versão ligeiramente modificada do script ShaChris23.Verifica se o valor proc_name é encontrado na string de argumentos do processo (por exemplo, script Python executado com python):
def process_exists(proc_name):
ps = subprocess.Popen("ps ax -o pid= -o args= ", shell=True, stdout=subprocess.PIPE)
ps_pid = ps.pid
output = ps.stdout.read()
ps.stdout.close()
ps.wait()
for line in output.split("\n"):
res = re.findall("(\d+) (.*)", line)
if res:
pid = int(res[0][0])
if proc_name in res[0][1] and pid != os.getpid() and pid != ps_pid:
return True
return False