Me encanta la simplicidad de esta respuesta. Para su información, debe poder agregar el indicador -f a pgrep, y luego puede verificar el nombre completo del proceso, lo cual es útil si también desea inspeccionar los argumentos del proceso como parte de su condición.
Craig Sefton
66
No, no puedes usar la bandera -f con pgrep dentro de un cronjob. La razón es que coincidirá con el script de shell utilizado para ejecutar el cronjob.
CpnCrunch
Cuando ejecute un proceso de GUI con cron, agregue ante export DISPLAY=:0para evitar Could not connect to displayerrores. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Benjam
9
Ejecute un script, en lugar de directamente el programa. Hay muchas posibilidades Por ejemplo :
MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
$RESTART
fi
FYI: el uso de variables escalares para almacenar listas de argumentos se considera una mala práctica. Consulte mywiki.wooledge.org/BashFAQ/050 para ver un ejemplo de un caso en el que falla.
Charles Duffy
... de manera similar, pgrep myprog; if [ $? -ne 0 ]; then ...estaría mejor escrito comoif ! pgrep myprog; then ...
Charles Duffy, el
... este último estilo no solo es más legible, sino que también es menos propenso a errores: es fácil alterar involuntariamente el valor de $?, por ejemplo, agregando mensajes de registro o manejo de errores entre líneas.
Charles Duffy
7
Este script no se ejecutará nuevamente si la instancia anterior no ha terminado. Si no desea ejecutar algo si se está ejecutando otro proceso específico, consulte el script de harrymc.
DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;
if flock -n -x 8; then
echo ""
echo "Starting your script..."
echo ""
[PUT YOUR STUFF HERE]
echo ""
echo "Script started $DATE";
echo "Script finished `date +%c`";
else
echo "Script NOT started - previous one still running at $DATE";
fi
bueno uno! ahora rsync sobre esta línea lenta puede tomar todo el tiempo que necesita, disparando dentro de los 5 minutos */5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
posteriores a la conexión del
1
Esto generalmente es manejado por el programa en sí mismo en lugar de hacerlo cron. Hay dos técnicas estándar para esto:
1) grepla salida de pspara ver si ya se está ejecutando un proceso con ese nombre
2) Al inicio, primero verifique la existencia de un archivo pid (id de proceso), generalmente en /var/run/program_name.pid, y, si existe, lea el pid del archivo y verifique si ese proceso todavía existe; si lo hace, rehúse comenzar. Si el archivo pid no existe o el pid en el archivo se ha ido, cree un archivo pid, escriba su identificación de proceso y continúe con el inicio normal.
Si bien es técnicamente posible escribir tubos de bash que harán cualquiera de estos directamente en su crontab, es mejor agregarlos al programa que se está iniciando (para que se apliquen sin importar cómo se inicie) o escribir un script de envoltura para manejar esto, como sugirió harrymc.
He reutilizado la respuesta anterior con una mejora en la coincidencia de patrones. pgrep sin la opción f no coincide con el patrón de proceso. Sin embargo, hay un problema con el uso de la opción f. Con la opción f, el shell que genera el cron siempre coincide y devuelve su pid, por lo tanto, el proceso nunca se reinicia.
Agregar un [] alrededor de uno de los patrones de letras coincide solo con el proceso y no se devuelve el pid del cron shell.
Respuestas:
de la manera más simple, use pgrep
en crontab:
fuente
export DISPLAY=:0
para evitarCould not connect to display
errores.* * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Ejecute un script, en lugar de directamente el programa. Hay muchas posibilidades Por ejemplo :
fuente
pgrep myprog; if [ $? -ne 0 ]; then ...
estaría mejor escrito comoif ! pgrep myprog; then ...
$?
, por ejemplo, agregando mensajes de registro o manejo de errores entre líneas.Este script no se ejecutará nuevamente si la instancia anterior no ha terminado. Si no desea ejecutar algo si se está ejecutando otro proceso específico, consulte el script de harrymc.
fuente
Puede usar un archivo de bloqueo en su secuencia de comandos, pero consulte Gestión de procesos .
flock
es una utilidad que se puede usar.fuente
*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
Esto generalmente es manejado por el programa en sí mismo en lugar de hacerlo
cron
. Hay dos técnicas estándar para esto:1)
grep
la salida deps
para ver si ya se está ejecutando un proceso con ese nombre2) Al inicio, primero verifique la existencia de un archivo pid (id de proceso), generalmente en
/var/run/program_name.pid
, y, si existe, lea el pid del archivo y verifique si ese proceso todavía existe; si lo hace, rehúse comenzar. Si el archivo pid no existe o el pid en el archivo se ha ido, cree un archivo pid, escriba su identificación de proceso y continúe con el inicio normal.Si bien es técnicamente posible escribir tubos de bash que harán cualquiera de estos directamente en su crontab, es mejor agregarlos al programa que se está iniciando (para que se apliquen sin importar cómo se inicie) o escribir un script de envoltura para manejar esto, como sugirió harrymc.
fuente
* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1
He reutilizado la respuesta anterior con una mejora en la coincidencia de patrones. pgrep sin la opción f no coincide con el patrón de proceso. Sin embargo, hay un problema con el uso de la opción f. Con la opción f, el shell que genera el cron siempre coincide y devuelve su pid, por lo tanto, el proceso nunca se reinicia.
Agregar un [] alrededor de uno de los patrones de letras coincide solo con el proceso y no se devuelve el pid del cron shell.
fuente