¿Cómo puedo determinar si un proceso se está ejecutando o no y luego hacer que un script bash ejecute algunas cosas en función de esa condición?
Por ejemplo:
si el proceso se
abc
está ejecutando, haz estosi no se está ejecutando, hazlo.
¿Cómo puedo determinar si un proceso se está ejecutando o no y luego hacer que un script bash ejecute algunas cosas en función de esa condición?
Por ejemplo:
si el proceso se abc
está ejecutando, haz esto
si no se está ejecutando, hazlo.
Respuestas:
Un script bash para hacer algo así se vería así:
#!/bin/bash
# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern.
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Stopped"
fi
Este script solo está verificando si el programa "gedit" se está ejecutando.
O solo puede verificar si el programa no se ejecuta así:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
/dev/null
: "/ dev / null redirige la salida estándar del comando al dispositivo nulo, que es un dispositivo especial que descarta la información escrita en él" ... el uso 0
redirigiría la salida del comando a un archivo llamado 0
. En este caso, te aconsejaría > /dev/null
que te sientas más cómodo : lo verás en todas partes, ya que es la forma estándar / adecuada de descartar la salida.
-x
parámetro para pgrep
que busque la aplicación exacta o, de lo contrario, obtendrá una falsa corrección si encuentra la misma cadena dentro del nombre de otra aplicación. Acabo de pasar 1 hora para descubrirlo.
! pgrep
Cualquier solución que use algo como ps aux | grep abc
opgrep abc
sea defectuosa.
Debido a que no está verificando si se está ejecutando un proceso específico, está verificando si hay algún proceso en ejecución que coincida abc
. Cualquier usuario puede crear y ejecutar fácilmente un archivo ejecutable llamado abc
(o que contenga abc
en algún lugar de su nombre o argumentos), causando un falso positivo para su prueba. Hay varias opciones a las que puede postularse ps
, grep
ypgrep
de restringir la búsqueda, pero todavía no conseguirán una prueba fiable.
Eso depende de para qué necesita la prueba.
Para eso están init y advenedizo. Comenzarán el servicio y se asegurarán de que su pid se almacene en un archivo pid. Intente iniciar el servicio nuevamente (a través de init o upstart) y verificará el archivo pid, y lo iniciará si no está allí, o abortará si ya se está ejecutando. Esto todavía no es 100% confiable, pero es lo más cercano posible.
Vea ¿Cómo puedo verificar si mi servidor de juegos aún se está ejecutando? ... para otras soluciones.
En este caso, use un archivo de bloqueo o un lockdir. P.ej
#!/usr/bin/env bash
if ! mkdir /tmp/abc.lock; then
printf "Failed to acquire lock.\n" >&2
exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT # remove the lockdir on exit
# rest of script ...
Vea Bash FAQ 45 para otras formas de bloqueo.
pgrep
o ps
es perfectamente adecuado y su enfoque parece excesivo. Sin embargo, si está escribiendo un script para distribución pública, debe escribirlo de la manera más segura posible.
rm
comando se ejecuta. Por lo tanto, siempre que termine después de que se haya establecido la trampa, el bloqueo debería desaparecer.
Esto es lo que uso:
#!/bin/bash
#check if abc is running
if pgrep abc >/dev/null 2>&1
then
# abc is running
else
# abc is not running
fi
En inglés simple: si 'pgrep' devuelve 0, el proceso se está ejecutando, de lo contrario no lo está.
Lectura relacionada:
Bash Scripting :: Comparaciones de cadenas
Manuales de Ubuntu pgrep
pgrep
tiene el mismo "característica" de 15 caracteres límite anteriormente mencionado, así por ejemplo pgrep gnome-power-manager
también fallaría
-x
opción pgrep : "Solo coincide con los procesos cuyo nombre (o línea de comando si se especifica -f) coincide exactamente con el patrón".
Por lo general, tengo un pidof -x $(basename $0)
en mis scripts para verificar si ya se está ejecutando.
Refiriéndose a la idea de @ rommel-cid, puede usar pidof
con el || (||) para ejecutar un comando si el proceso no existe y && para ejecutar algo si el proceso existe, creando así un condicional rápido if / then / else. Por ejemplo, aquí hay uno con un proceso en ejecución (mi navegador Chrome, cuyo nombre de proceso es "Chrome") y otro que prueba un proceso que no existe. Suprimí la salida estándar usando 1> / dev / null para que no se imprima:
$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
instead"
it's not running? ok i'll run instead
$
Ninguna de las soluciones "simples" funcionó para mí porque el binario que necesito verificar no está instalado en todo el sistema, por lo que tengo que verificar con la ruta, que a su vez requiere el uso de ps -ef | grep
enfoque:
app="$_sdir/Logic 1.2.18 (64-bit)/Logic"
app_pid=`ps -ef | grep "$app" | awk '{print $2}'`
if `ps -p $app_pid > /dev/null`; then
echo "An instance of logic analyzer is appear to be running."
echo "Not starting another instance."
exit 5
else
nohup "$app" &> /dev/null &
fi
Lo primero que me vino a la mente para su problema:
ps aux | grep -i abc
mostrará los detalles del proceso si se está ejecutando. Puede hacer coincidir el número de líneas o el tiempo durante el cual se ejecuta y comparar con cero o cualquier otra manipulación. Cuando ejecute el comando anterior, le mostrará al menos una línea de salida, es decir, detalles sobre el proceso creado por el comando grep. Así que tenga cuidado con eso.
Eso debería hacer como un simple truco. Póngalo en el script bash y vea si es útil.
Utilizando start-stop-daemon
:
/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2
Funciona como usuario normal.
Descubrí que la respuesta aceptada publicada por @John Vrbanac no funcionó para mí, y que la respuesta publicada por @geirha no responde a la pregunta original.
La solución de John Vrbanac no funcionó para verificar si un proceso PHP se estaba ejecutando o no para mí, estoy ejecutando CentOS 7.
La respuesta de @ geirha solo asegura que una instancia no se esté ejecutando antes de comenzar otra. Esta no era la pregunta original, la pregunta original era verificar si un proceso se está ejecutando o no.
Esto es lo que funcionó para mí:
Digamos que mi proceso tenía la cadena "Jane" en su nombre de proceso. Esto encontrará si se está ejecutando o no. Esto funciona para los scripts BASH y PHP.
ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
echo "It's running"
else
echo "It's not running"
fi
## bash
## function to check if a process is alive and running:
_isRunning() {
ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}
## example 1: checking if "gedit" is running
if _isRunning gedit; then
echo "gedit is running"
else
echo "gedit is not running"
fi
## example 2: start lxpanel if it is not there
if ! _isRunning lxpanel; then
lxpanel &
fi
## or
_isRunning lxpanel || (lxpanel &)
Nota : pgrep -x lxpanel
o pidof lxpanel
aún informa que se lxpanel
está ejecutando incluso cuando está inactivo (zombie); así que para obtener un proceso vivo y en funcionamiento, necesitamos usar ps
ygrep
A partir del 23 de septiembre de 2016, pgrep parece requerir una opción "-x" para que el script de muru funcione.
#!/bin/bash
if pgrep -x "conky" > /dev/null 2>&1
then
echo "conky running already"
else
echo "now starting conky"
conky
fi
exit 0
Probé y probé el script anterior en una máquina Ubuntu 16.04.1. ¡Disfrutar!
#!/bin/bash
while [ true ]; do # Endless loop.
pid=`pgrep -x ${1}` # Get a pid.
if [ -z $pid ]; then # If there is none,
${1} & # Start Param to background.
else
sleep 60 # Else wait.
fi
done
zombie
proceso '(No es lo que describiría como un proceso "en ejecución"). Aquí se encuentra una lista completa de lo que indican losSTAT
valores de la columna, en la salida deps
, para aquellos inclinados a escribir una respuesta que se adapte a esto, o editar la suya propia.