GNU bash, versión 1.14.7(1)
Tengo un script se llama "abc.sh
"
Tengo que comprobar esto sólo desde el script abc.sh
...
dentro de ella he escrito siguiente declaración
status=`ps -efww | grep -w "abc.sh" | grep -v grep | grep -v $$ | awk '{ print $2 }'`
if [ ! -z "$status" ]; then
echo "[`date`] : abc.sh : Process is already running"
exit 1;
fi
Se que esta mal porque cada vez que sale encuentra su propio proceso en 'ps'
¿cómo solucionarlo?
¿cómo puedo comprobar si el script ya se está ejecutando o no sólo desde ese script
?
Una forma más sencilla de comprobar si un proceso ya se está ejecutando es el comando pidof
.
if pidof -x "abc.sh" >/dev/null; then
echo "Process already running"
fi
Alternativamente, haga que su script cree un archivo PID cuando se ejecute. Es entonces un simple ejercicio de comprobar la presencia del archivo PID para determinar si el proceso ya se está ejecutando.
#!/bin/bash
# abc.sh
mypidfile=/var/run/abc.sh.pid
# Could add check for existence of mypidfile here if interlock is
# needed in the shell script itself.
# Ensure PID file is removed on program exit.
trap "rm -f -- '$mypidfile'" EXIT
# Create a file with current PID to indicate that process is running.
echo $$ > "$mypidfile"
...
Actualización:
La pregunta ha cambiado ahora para comprobar desde el propio script. En este caso, esperaríamos ver siempre al menos un abc.sh
ejecutándose. Si hay más de un abc.sh
, entonces sabemos que el proceso sigue en ejecución. Yo sugeriría usar el comando pidof
que devolvería 2 PIDs si el proceso ya estuviera en ejecución. Puedes usar grep
para filtrar el PID actual, hacer un bucle en el shell o incluso volver a contar los PIDs con wc
para detectar múltiples procesos.
He aquí un ejemplo:
#!/bin/bash
for pid in $(pidof -x abc.sh); do
if [ $pid != $$ ]; then
echo "[$(date)] : abc.sh : Process is already running with PID $pid"
exit 1
fi
done
He aquí un truco que verás en varios sitios:
status=`ps -efww | grep -w "[a]bc.sh" | awk -vpid=$$ '$2 != pid { print $2 }'`
if [ ! -z "$status" ]; then
echo "[`date`] : abc.sh : Process is already running"
exit 1;
fi
Los corchetes alrededor de la [a]
(o elige una letra diferente) evitan que grep
se encuentre a sí mismo. Esto hace que el bit grep -v grep
sea innecesario. También eliminé grep -v $$
y arreglé la parte awk
para lograr lo mismo.
Que alguien me eche la culpa si me equivoco.
Entiendo que la operación mkdir
es atómica, así que podrías crear un directorio de bloqueo
#!/bin/sh
lockdir=/tmp/AXgqg0lsoeykp9L9NZjIuaqvu7ANILL4foeqzpJcTs3YkwtiJ0
mkdir $lockdir || {
echo "lock directory exists. exiting"
exit 1
}
# take pains to remove lock directory when script terminates
trap "rmdir $lockdir" EXIT INT KILL TERM
# rest of script here