¿Cómo determinar si un proceso se está ejecutando o no y usarlo para crear un script de shell condicional?

89

¿Cómo puedo determinar si un proceso se está ejecutando o no y luego hacer que un script de bash ejecute algunas cosas según esa condición?

Por ejemplo:

  • si el proceso abc se está ejecutando, haga esto

  • si no se está ejecutando, haz eso.

pregunta Nirmik 29.06.2012 - 23:53

12 respuestas

146

Un script de 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á comprobando si el programa "gedit" se está ejecutando.

O solo puede verificar si el programa no se está ejecutando así:

if ! pgrep -x "gedit" > /dev/null
then
    echo "Stopped"
fi
    
respondido por el John Vrbanac 30.06.2012 - 00:08
32

Cualquier solución que use algo como ps aux | grep abc o pgrep abc tiene fallas.

¿Por qué?

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 con abc . Cualquier usuario puede crear y ejecutar fácilmente un ejecutable llamado abc (o que contenga abc en algún lugar en su nombre o argumentos), lo que genera un falso positivo para su prueba. Existen varias opciones que puede aplicar a ps , grep y pgrep para limitar la búsqueda, pero aún no obtendrá una prueba confiable.

Entonces, ¿cómo puedo probar de forma confiable un determinado proceso en ejecución?

Eso depende de lo que necesite la prueba.

Quiero asegurarme de que el servicio abc se esté ejecutando y, en caso contrario, inícielo

Esto es para lo que son init y upstart. 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 a ti.

Ver para otras soluciones.

abc es mi script. Necesito asegurarme de que solo se ejecute una instancia de mi script.

En este caso, use un archivo de bloqueo o un lockdir. Por ejemplo,

#!/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 ...

Consulte Bash FAQ 45 para conocer otras formas de bloqueo.

    
respondido por el geirha 30.06.2012 - 09:29
17

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 es.

Lectura relacionada:

Bash Scripting :: Comparaciones de cadenas

Manuales de Ubuntu pgrep

    
respondido por el Zuul 30.06.2012 - 00:15
5

Por lo general, tengo un pidof -x $(basename $0) en mis scripts para verificar si ya se está ejecutando.

    
respondido por el Rommel Cid 14.01.2014 - 10:42
1

Riffing en la idea de @rommel-cid, puedes 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 si / then / else rápido. Por ejemplo, aquí hay uno con un proceso en ejecución (mi navegador chrome, cuyo nombre de proceso es "chrome") y uno 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
$
    
respondido por el yuvilio 02.03.2014 - 00:08
0

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 está ejecutando y comparar con cero o con 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 thi grep ... Así que cuídese.
Eso debería hacer como un simple truco. Póngalo en el script de bash y vea si es útil.

    
respondido por el drake01 30.06.2012 - 00:03
0

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.

    
respondido por el Martin Monperrus 19.06.2015 - 19:55
0

Encontré que la respuesta aceptada publicada por @John Vrbanac no funcionó para mí, y que la respuesta publicada por @geirha no responde la pregunta original.

La solución de John Vrbanac no funcionó para comprobar si un proceso de PHP se estaba ejecutando o no, estoy ejecutando CentOS 7.

La respuesta de @ geirha solo se asegura de que una instancia no se esté ejecutando antes de iniciar otra. Esta no era la pregunta original, la pregunta original era para verificar si un proceso se está ejecutando o no.

Esto es lo que funcionó para mí:

Diga que mi proceso tenía la cadena "Jane" en su nombre de proceso. Esto encontrará si está funcionando o no. Esto funciona para 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
    
respondido por el Wayne Workman 11.11.2016 - 20:12
0
## 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 lxpanel se está ejecutando incluso cuando está inactivo (zombie); por lo tanto, para obtener un proceso activo y en ejecución, necesitamos usar ps y grep

    
respondido por el Bach Lien 23.12.2017 - 19:01
-1

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. ¡Disfruta!

    
respondido por el dzmanto 23.09.2016 - 20:39
-1
#!/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
    
respondido por el user7449824 28.01.2017 - 19:36
-3

isProcessRunning () {if [$ (pidof $ 1) > / dev / null]; entonces retval = 'true'; else retval = 'false'; fi echo $ retval; }

isProcessRunning geany

true

    
respondido por el Dominic 19.01.2016 - 20:37

Lea otras preguntas en las etiquetas