tag - Verifique si el script python se está ejecutando
parser html python (19)
Aquí hay un código más útil (con la comprobación de si exactamente Python ejecuta el script):
#! /usr/bin/env python
import os
from sys import exit
def checkPidRunning(pid):
global script_name
if pid<1:
print "Incorrect pid number!"
exit()
try:
os.kill(pid, 0)
except OSError:
print "Abnormal termination of previous process."
return False
else:
ps_command = "ps -o command= %s | grep -Eq ''python .*/%s''" % (pid,script_name)
process_exist = os.system(ps_command)
if process_exist == 0:
return True
else:
print "Process with pid %s is not a Python process. Continue..." % pid
return False
if __name__ == ''__main__'':
script_name = os.path.basename(__file__)
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp/", script_name+".pid")
if os.path.isfile(pidfile):
print "Warning! Pid file %s existing. Checking for process..." % pidfile
r_pid = int(file(pidfile,''r'').readlines()[0])
if checkPidRunning(r_pid):
print "Python process with pid = %s is already running. Exit!" % r_pid
exit()
else:
file(pidfile, ''w'').write(pid)
else:
file(pidfile, ''w'').write(pid)
# main programm
....
....
os.unlink(pidfile)
Aquí está la cadena:
ps_command = "ps -o command= %s | grep -Eq ''python .*/%s''" % (pid,script_name)
devuelve 0 si "grep" es exitoso, y el proceso "python" se está ejecutando actualmente con el nombre de su script como parámetro.
Tengo un daemon python ejecutándose como parte de mi aplicación web / ¿Cómo puedo verificar rápidamente (usando Python) si mi daemon se está ejecutando y, si no, lo ejecuto?
Quiero hacerlo de esa forma para solucionar cualquier falla del daemon, por lo que no es necesario ejecutar el script manualmente, se ejecutará automáticamente tan pronto como se llame y luego se mantendrá en funcionamiento.
¿Cómo puedo verificar (usando Python) si mi script se está ejecutando?
Coloque un archivo pid en algún lugar (p. Ej. / Tmp). Luego puede verificar si el proceso se está ejecutando comprobando si el PID en el archivo existe. No se olvide de borrar el archivo cuando se apaga limpiamente, y verifíquelo cuando se inicie.
#/usr/bin/env python
import os
import sys
pid = str(os.getpid())
pidfile = "/tmp/mydaemon.pid"
if os.path.isfile(pidfile):
print "%s already exists, exiting" % pidfile
sys.exit()
file(pidfile, ''w'').write(pid)
try:
# Do some actual work here
finally:
os.unlink(pidfile)
Luego puede verificar si el proceso se está ejecutando comprobando si el contenido de /tmp/mydaemon.pid es un proceso existente. Monit (mencionado anteriormente) puede hacer esto por usted, o puede escribir un simple script de shell para verificarlo utilizando el código de retorno de ps.
ps up `cat /tmp/mydaemon.pid ` >/dev/null && echo "Running" || echo "Not running"
Para obtener más crédito, puede usar el módulo atexit para asegurarse de que su programa limpie su archivo pidfile bajo cualquier circunstancia (cuando muere, se levantan excepciones, etc.).
Considere el siguiente ejemplo para resolver su problema:
#!/usr/bin/python
# -*- coding: latin-1 -*-
import os, sys, time, signal
def termination_handler (signum,frame):
global running
global pidfile
print ''You have requested to terminate the application...''
sys.stdout.flush()
running = 0
os.unlink(pidfile)
running = 1
signal.signal(signal.SIGINT,termination_handler)
pid = str(os.getpid())
pidfile = ''/tmp/''+os.path.basename(__file__).split(''.'')[0]+''.pid''
if os.path.isfile(pidfile):
print "%s already exists, exiting" % pidfile
sys.exit()
else:
file(pidfile, ''w'').write(pid)
# Do some actual work here
while running:
time.sleep(10)
Sugiero esta secuencia de comandos porque solo se puede ejecutar una vez.
En lugar de desarrollar su propia solución de archivos PID (que tiene más sutilezas y casos de esquina de los que podría pensar), eche un vistazo a supervisord : este es un sistema de control de procesos que facilita el control del trabajo y el comportamiento de daemon en una Python existente guión.
Esto es lo que uso en Linux para evitar iniciar un script si ya se está ejecutando:
import os
import sys
script_name = os.path.basename(__file__)
pidfile = os.path.join("/tmp", os.path.splitext(script_name)[0]) + ".pid"
def create_pidfile():
if os.path.exists(pidfile):
with open(pidfile, "r") as _file:
last_pid = int(_file.read())
# Checking if process is still running
last_process_cmdline = "/proc/%d/cmdline" % last_pid
if os.path.exists(last_process_cmdline):
with open(last_process_cmdline, "r") as _file:
cmdline = _file.read()
if script_name in cmdline:
raise Exception("Script already running...")
with open(pidfile, "w") as _file:
pid = str(os.getpid())
_file.write(pid)
def main():
"""Your application logic goes here"""
if __name__ == "__main__":
create_pidfile()
main()
Este enfoque funciona bien sin ninguna dependencia de un módulo externo.
Hay paquetes muy buenos para reiniciar procesos en UNIX. Uno que tiene un gran tutorial sobre cómo construirlo y configurarlo es monit . Con algunos ajustes, puede tener una tecnología sólida y sólida para mantener a su daemon.
Hay una infinidad de opciones. Un método es usar llamadas al sistema o bibliotecas de Python que realizan esas llamadas por usted. El otro es simplemente generar un proceso como:
ps ax | grep processName
y analizar la salida. Mucha gente elige este enfoque, no es necesariamente un mal enfoque en mi opinión.
La biblioteca pid puede hacer exactamente esto.
from pid import PidFile
with PidFile():
do_something()
También manejará automáticamente el caso donde existe el archivo pid pero el proceso no se está ejecutando.
Las otras respuestas son geniales para cosas como tareas cron, pero si estás ejecutando un daemon debes monitorearlo con algo así como daemontools .
Me encontré con esta vieja pregunta buscando la solución yo mismo.
Use psutil :
import psutil
import sys
from subprocess import Popen
for process in psutil.process_iter():
if process.cmdline() == [''python'', ''your_script.py'']:
sys.exit(''Process found: exiting.'')
print(''Process not found: starting it.'')
Popen([''python'', ''your_script.py''])
Mi solución es verificar el proceso y los argumentos de la línea de comando Probado en Windows y Ubuntu Linux
import psutil
import os
def is_running(script):
for q in psutil.process_iter():
if q.name().startswith(''python''):
if len(q.cmdline())>1 and script in q.cmdline()[1] and q.pid !=os.getpid():
print("''{}'' Process is already running".format(script))
return True
return False
if not is_running("test.py"):
n = input("What is Your Name? ")
print ("Hello " + n)
Por supuesto, el ejemplo de Dan no funcionará como debería ser.
De hecho, si el script falla, sube una excepción o no limpia el archivo pid, el script se ejecutará varias veces.
Sugiero lo siguiente basado en otro sitio web:
Esto es para verificar si ya existe un archivo de bloqueo
/#/usr/bin/env python
import os
import sys
if os.access(os.path.expanduser("~/.lockfile.vestibular.lock"), os.F_OK):
#if the lockfile is already there then check the PID number
#in the lock file
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "r")
pidfile.seek(0)
old_pid = pidfile.readline()
# Now we check the PID from lock file matches to the current
# process PID
if os.path.exists("/proc/%s" % old_pid):
print "You already have an instance of the program running"
print "It is running as process %s," % old_pid
sys.exit(1)
else:
print "File is there but the program is not running"
print "Removing lock file for the: %s as it can be there because of the program last time it was run" % old_pid
os.remove(os.path.expanduser("~/.lockfile.vestibular.lock"))
Esto es parte del código donde ponemos un archivo PID en el archivo de bloqueo
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()
Este código verificará el valor de pid en comparación con el proceso en ejecución existente, evitando la doble ejecución.
Espero que ayude
Prueba esta otra versión
def checkPidRunning(pid):
''''''Check For the existence of a unix pid.
''''''
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
# Entry point
if __name__ == ''__main__'':
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp", __program__+".pid")
if os.path.isfile(pidfile) and checkPidRunning(int(file(pidfile,''r'').readlines()[0])):
print "%s already exists, exiting" % pidfile
sys.exit()
else:
file(pidfile, ''w'').write(pid)
# Do some actual work here
main()
os.unlink(pidfile)
Soy un gran admirador de supervisord para administrar daemons. Está escrito en Python, por lo que hay muchos ejemplos de cómo interactuar o ampliarlo desde Python. Para sus propósitos, la API de control de procesos XML-RPC debería funcionar bien.
Una técnica que es útil en un sistema Linux es usar sockets de dominio:
import socket
import sys
import time
def get_lock(process_name):
# Without holding a reference to our socket somewhere it gets garbage
# collected when the function exits
get_lock._lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
try:
get_lock._lock_socket.bind(''/0'' + process_name)
print ''I got the lock''
except socket.error:
print ''lock exists''
sys.exit()
get_lock(''running_test'')
while True:
time.sleep(3)
Es atómico y evita el problema de tener archivos de bloqueo por ahí si a su proceso se le envía un SIGKILL
Puede leer en la documentación de socket.close
que los sockets se cierran automáticamente cuando se recolecta la basura.
Usar bash para buscar un proceso con el nombre del guión actual. Sin archivo adicional.
import commands
import os
import time
import sys
def stop_if_already_running():
script_name = os.path.basename(__file__)
l = commands.getstatusoutput("ps aux | grep -e ''%s'' | grep -v grep | awk ''{print $2}''| awk ''{print $2}''" % script_name)
if l[1]:
sys.exit(0);
Para probar, agregar
stop_if_already_running()
print "running normally"
while True:
time.sleep(3)
prueba esto:
#/usr/bin/env python
import os, sys, atexit
try:
# Set PID file
def set_pid_file():
pid = str(os.getpid())
f = open(''myCode.pid'', ''w'')
f.write(pid)
f.close()
def goodby():
pid = str(''myCode.pid'')
os.remove(pid)
atexit.register(goodby)
set_pid_file()
# Place your code here
except KeyboardInterrupt:
sys.exit(0)
Un simple ejemplo si solo está buscando un nombre de proceso existe o no:
import os
def pname_exists(inp):
os.system(''ps -ef > /tmp/psef'')
lines=open(''/tmp/psef'', ''r'').read().split(''/n'')
res=[i for i in lines if inp in i]
return True if res else False
Result:
In [21]: pname_exists(''syslog'')
Out[21]: True
In [22]: pname_exists(''syslog_'')
Out[22]: False
ps ax | grep processName
si su script de depuración en pycharm siempre sale
pydevd.py --multiproc --client 127.0.0.1 --port 33882 --file processName