script reiniciar manualmente instalar inicio ejemplos ejecutar ejecuta editar linux bash cron watchdog

linux - reiniciar - Ejecute el trabajo cron solo si no se está ejecutando



instalar crontab ubuntu (15)

Así que estoy tratando de configurar un trabajo cron como una especie de perro guardián para un daemon que he creado. Si el daemon se equivoca y falla, quiero que el trabajo cron lo reinicie periódicamente ... No estoy seguro de qué tan posible es esto, pero leí un par de tutoriales cron y no pude encontrar nada que hiciera lo que Estoy buscando ...

My daemon se inicia desde un script de shell, así que solo estoy buscando una manera de ejecutar un trabajo cron SOLO si la ejecución anterior de ese trabajo aún no se está ejecutando.

Encontré esta publicación , que proporcionó una solución para lo que estoy tratando de hacer usando archivos de bloqueo, no estoy seguro de si hay una mejor manera de hacerlo ...

Gracias por tu ayuda.


Como otros han declarado, escribir y verificar un archivo PID es una buena solución. Aquí está mi implementación de bash:

#!/bin/bash mkdir -p "$HOME/tmp" PIDFILE="$HOME/tmp/myprogram.pid" if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -opid= | grep -P "^/s*$(cat ${PIDFILE})$" &> /dev/null); then echo "Already running." exit 99 fi /path/to/myprogram > $HOME/tmp/myprogram.log & echo $! > "${PIDFILE}" chmod 644 "${PIDFILE}"


Como seguimiento de la respuesta de Earlz, necesita un script de envoltura que cree un archivo $ PID.running cuando se inicie, y elimínelo cuando termine. El script de contenedor llama al script que desea ejecutar. El contenedor es necesario en caso de que la secuencia de comandos de destino falle o los errores salgan, el archivo pid se elimina.



Considere usar pgrep (si está disponible) en lugar de ps por grep si va a seguir esa ruta. Aunque, personalmente, obtuve mucho kilometraje de los guiones del formulario

while(1){ call script_that_must_run sleep 5 }

Aunque esto puede fallar y los trabajos de cron son a menudo la mejor manera para cosas esenciales. Solo otra alternativa.


Es sorprendente que nadie haya mencionado sobre el run-one . He resuelto mi problema con esto.

apt-get install run-one

luego agrega run-one antes de tu script crontab

*/20 * * * * * run-one python /script/to/run/awesome.py

Mira this respuesta askubuntu SE. Puede encontrar un enlace a una información detallada allí también.


Hago esto para un programa de cola de impresión que escribí, es solo un script de shell:

#!/bin/sh if ps -ef | grep -v grep | grep doctype.php ; then exit 0 else /home/user/bin/doctype.php >> /home/user/bin/spooler.log & #mailing program /home/user/bin/simplemail.php "Print spooler was not running... Restarted." exit 0 fi

Corre cada dos minutos y es bastante efectivo. Lo tengo por correo electrónico con información especial si por alguna razón el proceso no se está ejecutando.


La forma en que lo estoy haciendo cuando estoy ejecutando scripts php es:

El crontab:

* * * * * php /path/to/php/script.php &

El código php:

<?php if (shell_exec(''ps aux | grep '' . __FILE__ . '' | wc -l'') > 1) { exit(''already running...''); } // do stuff

Este comando está buscando en la lista de procesos del sistema para el nombre de archivo php actual, si existe, el contador de líneas (wc -l) será mayor que uno porque el comando de búsqueda contiene el nombre del archivo

así que si ejecutas php crons agrega el código anterior al inicio de tu código php y se ejecutará solo una vez.


No intentes hacerlo a través de cron. Haga que cron ejecute un script sin importar qué, y luego haga que el script decida si el programa se está ejecutando e inícielo si es necesario (tenga en cuenta que puede usar Ruby o Python o su lenguaje de scripting favorito para hacer esto)


Simple PHP personalizado es suficiente para lograrlo. No hay necesidad de confundir con el script de shell.

supongamos que quieres ejecutar php /home/mypath/example.php si no se está ejecutando

A continuación, utilice la siguiente secuencia de comandos personalizada de PHP para hacer el mismo trabajo.

crear siguiente /home/mypath/forever.php

<?php $cmd = $argv[1]; $grep = "ps -ef | grep ''".$cmd."''"; exec($grep,$out); if(count($out)<5){ $cmd .= '' > /dev/null 2>/dev/null &''; exec($cmd,$out); print_r($out); } ?>

Luego en tu cron agrega lo siguiente

* * * * * php /home/mypath/forever.php ''php /home/mypath/example.php''


Sugeriría lo siguiente como una mejora a la respuesta de rsanden (lo publicaría como un comentario, pero no tengo suficiente reputación ...):

#!/usr/bin/env bash PIDFILE="$HOME/tmp/myprogram.pid" if [ -e "${PIDFILE}" ] && (ps -p $(cat ${PIDFILE}) > /dev/null); then echo "Already running." exit 99 fi /path/to/myprogram

Esto evita posibles coincidencias falsas (y la sobrecarga de grepping), y suprime la salida y se basa únicamente en el estado de salida de ps.


También puede hacerlo como una línea directamente en su crontab:

* * * * * [ `ps -ef|grep -v grep|grep <command>` -eq 0 ] && <command>


Usa flock Es nuevo. Es mejor.

Ahora no tiene que escribir el código usted mismo. Consulte más motivos aquí: https://serverfault.com/a/82863

/usr/bin/flock -n /tmp/my.lockfile /usr/local/bin/my_script


Yo recomendaría usar una herramienta existente como monit , supervisará y reiniciará procesos automáticamente. Hay más información disponible here . Debería estar fácilmente disponible en la mayoría de las distribuciones.


Este nunca me falló:

one.sh :

LFILE=/tmp/one-`echo "$@" | md5sum | cut -d/ -f1`.pid if [ -e ${LFILE} ] && kill -0 `cat ${LFILE}`; then exit fi trap "rm -f ${LFILE}; exit" INT TERM EXIT echo $$ > ${LFILE} $@ rm -f ${LFILE}

trabajo de cron :

* * * * * /path/to/one.sh <command>


# one instance only (works unless your cmd has ''grep'' in it) ALREADY_RUNNING_EXIT_STATUS=0 bn=`basename $0` proc=`ps -ef | grep -v grep | grep "$bn" | grep -v " $$ "` [ $? -eq 0 ] && { pid=`echo $proc | awk ''{print $2}''` echo "$bn already running with pid $pid" exit $ALREADY_RUNNING_EXIT_STATUS }