¿Cómo escribo un script bash para reiniciar un proceso si muere?
Tengo un script en Python que verificará una cola y realizará una acción en cada elemento:
# checkqueue.py
while True:
check_queue()
do_something()
¿Cómo escribo un script bash que comprobará si se está ejecutando y, si no, lo iniciará? Aproximadamente el siguiente pseudocódigo (¿o tal vez debería hacer algo como ps | grep
?):
# keepalivescript.sh
if processidfile exists:
if processid is running:
exit, all ok
run checkqueue.py
write processid to processidfile
Lo llamaré desde un crontab:
# crontab
*/5 * * * * /path/to/keepalivescript.sh
Evite archivos PID, crons o cualquier otra cosa que intente evaluar procesos que no sean sus hijos.
Hay una muy buena razón por la cual en UNIX SÓLO puedes atender a tus hijos. Cualquier método (ps análisis, pgrep, almacenamiento de un PID, ...) que intente solucionarlo es defectuoso y tiene grandes agujeros. Solo di no .
En su lugar, necesita que el proceso que monitorea su proceso sea el padre del proceso. ¿Qué quiere decir esto? Significa que solo el proceso que inicia su proceso puede esperar de manera confiable a que finalice. En bash, esto es absolutamente trivial.
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
O para poder detenerlo:
trap 'kill $(jobs -p)' EXIT; until myserver & wait; do
echo "ldap proxy crashed with exit code $?. Respawning.." >&2
sleep 1
done
El fragmento de código bash anterior se ejecuta myserver
en un until
bucle. La primera línea comienza myserver
y espera a que termine. Cuando finaliza, until
comprueba su estado de salida. Si el estado de salida es 0
, significa que finalizó correctamente (lo que significa que le pidió que se cerrara de alguna manera y lo hizo con éxito). En ese caso, no queremos reiniciarlo (¡solo le pedimos que se apague!). Si el estado de salida no 0
es , until
se ejecutará el cuerpo del bucle, que emite un mensaje de error en STDERR y reinicia el bucle (de vuelta a la línea 1) después de 1 segundo .
¿Por qué esperamos un segundo? Porque si algo anda mal con la secuencia de inicio myserver
y falla inmediatamente, tendrás un ciclo muy intensivo de reinicios y fallas constantes en tus manos. Esto le sleep 1
quita la tensión a eso.
Ahora todo lo que necesita hacer es iniciar este script bash (probablemente de forma asincrónica), y lo monitoreará myserver
y reiniciará según sea necesario. Si desea iniciar el monitor al arrancar (haciendo que el servidor "sobreviva" los reinicios), puede programarlo en el cron(1) de su usuario con una @reboot
regla. Abra sus reglas cron con crontab
:
crontab -e
Luego agregue una regla para iniciar su secuencia de comandos de monitor:
@reboot /usr/local/bin/myservermonitor
Alternativamente; mire inittab(5) y /etc/inittab. Puede agregar una línea allí para myserver
comenzar en un cierto nivel de inicio y reaparecer automáticamente.
Editar.
Permítanme agregar información sobre por qué no usar archivos PID. Si bien son muy populares; también tienen muchos defectos y no hay ninguna razón por la que no lo hagas de la manera correcta.
Considera esto:
Reciclaje de PID (eliminando el proceso incorrecto):
/etc/init.d/foo start
: iniciarfoo
, escribirfoo
el PID en/var/run/foo.pid
- Un rato después:
foo
muere de alguna manera. - Un tiempo después: cualquier proceso aleatorio que se inicie (llámelo
bar
) toma un PID aleatorio, imagínese que tomafoo
el PID anterior. - Te das cuenta
foo
de que se ha ido:/etc/init.d/foo/restart
lee/var/run/foo.pid
, comprueba si todavía está vivo, lo encuentrabar
, cree que estáfoo
, lo mata, comienza una nuevafoo
.
Los archivos PID se vuelven obsoletos. Necesita una lógica demasiado complicada (o debería decir, no trivial) para comprobar si el archivo PID está obsoleto y si dicha lógica vuelve a ser vulnerable a
1.
.¿Qué pasa si ni siquiera tienes acceso de escritura o estás en un entorno de sólo lectura?
Es una complicación excesiva e inútil; Vea lo simple que es mi ejemplo anterior. No hay necesidad de complicar eso, en absoluto.
Ver también: ¿ Siguen siendo defectuosos los archivos PID cuando se hacen "bien"?
Por cierto; ¡Incluso peor que los archivos PID es el análisis ps
! Nunca hagas esto.
ps
Es muy poco portátil. Si bien lo encuentra en casi todos los sistemas UNIX; sus argumentos varían mucho si desea una salida no estándar. ¡Y la salida estándar es SÓLO para consumo humano, no para análisis mediante script!- El análisis
ps
conduce a MUCHOS falsos positivos. Tome elps aux | grep PID
ejemplo y ahora imagine a alguien iniciando un proceso con un número en algún lugar como argumento que resulta ser el mismo que el PID con el que miró su demonio. Imagina a dos personas iniciando una sesión X y tú buscando que X elimine la tuya. Es todo tipo de cosas malas.
Si no desea gestionar el proceso usted mismo; Existen algunos sistemas perfectamente buenos que actuarán como monitores de sus procesos. Mire runit , por ejemplo.
Eche un vistazo a monit ( http://mmonit.com/monit/ ). Maneja el inicio, la parada y el reinicio de su script y puede realizar comprobaciones de estado y reinicios si es necesario.
O haz un script simple:
while true
do
/your/script
sleep 1
done