2009-05-29 11 views
10

Tengo un script que se ejecuta cada 15 minutos pero a veces si el cuadro está ocupado se bloquea y el siguiente proceso se inicia antes de que el primero termine de crearse un efecto de bola de nieve. ¿Cómo puedo agregar un par de líneas al script bash para verificar si algo se está ejecutando primero antes de comenzar?Cómo verificar un script bash si algo se está ejecutando y salir si es

+1

Dupe de 185451. – Rob

+0

Ver [http://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at-a](http : //stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-runnin g-at-a). – Rob

+0

posible duplicado de [la ejecución de script de shell comprueba si ya se está ejecutando o no] (http://stackoverflow.com/questions/16807876/shell-script-execution-check-if-it-is-already-running-or- no) – Pureferret

Respuesta

3

En lugar de pidfiles, siempre y cuando la secuencia de comandos tiene un nombre único de identificación que puede hacer algo como esto:

#!/bin/bash 
COMMAND=$0 
# exit if I am already running 
RUNNING=`ps --no-headers -C${COMMAND} | wc -l` 
if [ ${RUNNING} -gt 1 ]; then 
    echo "Previous ${COMMAND} is still running." 
    exit 1 
fi 
... rest of script ... 
+3

Lo hice y Tuve que modificarlo un poco. En primer lugar, COMMAND incluye la ruta completa, por lo tanto, a menos que la ejecute desde el mismo directorio, no funcionará. Codifiqué el nombre de todos modos. Segundo, por alguna razón ps --no-headers -C $ {COMMAND} | wc -l siempre devolvió 1 sin nada en ejecución y dado que este script se está ejecutando mientras se comprueba que es otro 1, siempre regresó 2. Tuve que cambiar el -gt 1 por -gt 2 y funcionó. Gracias. –

3
pgrep -f yourscript >/dev/null && exit 
+0

pkill -0 yourscript probablemente sería mejor – iny

5

¿Por qué no se establece un archivo de bloqueo?

Algo así como

yourapp.lock

Basta con retirar cuando lo proceso ha terminado, y comprobar si antes de su inicio.

Se podría hacer uso de

if [ -f yourapp.lock ]; then 
echo "The process is already launched, please wait..." 
fi 
+1

Dado que la gestión correcta de un archivo de bloqueo, en particular el manejo del caso donde un proceso salió incorrectamente y no pudo borrar su archivo de bloqueo, toma más de un par de líneas en bash. – chaos

+1

Si usas 'flock', los archivos de bloqueo son fáciles de administrar, pero sí, usar' -f' para probar su existencia es Evil And Wrong. –

13

Puede utilizar pidof -x si se conoce el nombre del proceso, o kill -0 si se conoce el PID.

Ejemplo:

if pidof -x vim > /dev/null 
then 
    echo "Vim already running" 
    exit 1 
fi 
+1

Esta es la mejor manera. – olle

+1

Asegúrate de usar la bandera -x si estás revisando una secuencia de comandos, o no conseguirás una coincidencia, porque buscará 'bash' – Nathan

+1

si pidof solo fue parte de FreeBSD ... –

1

Para ampliar lo @bgy dice, la caja de seguridad atómica manera de crear un archivo de bloqueo si no existe todavía, y fallar si no lo hace, es crea un archivo temporal y luego vincúlalo al archivo de bloqueo estándar. Esto protege contra otro proceso que crea el archivo entre la prueba y la creación.

Aquí es el código de archivo de bloqueo de mi hora script de copia de seguridad:

echo $$ > /tmp/lock.$$ 
if ! ln /tmp/lock.$$ /tmp/lock ; then 
     echo "previous backup in process" 
     rm /tmp/lock.$$ 
     exit 
fi 

No se olvide de eliminar tanto el archivo de bloqueo y el archivo temporal cuando haya terminado, aun si sale temprano a través de una error.

1

Usar este comando:

FILE="/tmp/my_file" 
if [ -f "$FILE" ]; then 
    echo "Still running" 
    exit 
fi 
trap EXIT "rm -f $FILE" 
touch $FILE 

...script here... 

Este script creará un archivo y extraerlo en la salida.

2

recientemente he tenido la misma pregunta y se encontró desde arriba que matar a -0 es mejor para mi caso:

echo "Starting process..." 
run-process > $OUTPUT & 
pid=$! 
echo "Process started pid=$pid" 
while true; do 
    kill -0 $pid 2> /dev/null || { echo "Process exit detected"; break; } 
    sleep 1 
done 
echo "Done." 
3

Así es como lo hago en uno de mis trabajos cron

lockfile=~/myproc.lock 
minutes=60 
if [ -f "$lockfile" ] 
then 
    filestr=`find $lockfile -mmin +$minutes -print` 
    if [ "$filestr" = "" ]; then 
    echo "Lockfile is not older than $minutes minutes! Another $0 running. Exiting ..." 
    exit 1 
    else 
    echo "Lockfile is older than $minutes minutes, ignoring it!" 
    rm $lockfile 
    fi 
fi 

echo "Creating lockfile $lockfile" 
touch $lockfile 

y borrar el archivo de bloqueo al final de la secuencia de comandos

echo "Removing lock $lockfile ..." 
rm $lockfile 
Cuestiones relacionadas