Comando Linux / Unix para determinar si el proceso se está ejecutando

Necesito un comando shell / bash independiente de la plataforma (Linux / Unix | OSX) que determinará si se está ejecutando un proceso específico. ej. mysqld , httpd … ¿Cuál es la forma / comando más simple para hacer esto?

Si bien pidof y pgrep son excelentes herramientas para determinar qué se está ejecutando, lamentablemente no están disponibles en algunos sistemas operativos. Un fallo seguro definitivo sería usar lo siguiente: ps cax | grep command ps cax | grep command

La salida en Gentoo Linux:

 14484?  S 0:00 apache2
 14667?  S 0:00 apache2
 19620?  Sl 0:00 apache2
 21132?  Ss 0:04 apache2

La salida en OS X:

 42582?  Z 0: 00.00 (smbclient)
 46529 ??  Z 0: 00.00 (smbclient)
 46539 ??  Z 0: 00.00 (smbclient)
 46547 ??  Z 0: 00.00 (smbclient)
 46586 ??  Z 0: 00.00 (smbclient)
 46594 ??  Z 0: 00.00 (smbclient)

Tanto en Linux como en OS X, grep devuelve un código de salida por lo que es fácil verificar si el proceso se encontró o no:

 #!/bin/bash ps cax | grep httpd > /dev/null if [ $? -eq 0 ]; then echo "Process is running." else echo "Process is not running." fi 

Además, si desea la lista de PID, también puede obtener fácilmente los siguientes:

  ps cax |  grep httpd |  grep -o '^ [] * [0-9] *' 

Cuyo resultado es el mismo en Linux y OS X:

  3519 3521 3523 3524 

El resultado de lo siguiente es una cadena vacía, lo que hace que este enfoque sea seguro para los procesos que no se están ejecutando:

  echo ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*' ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*' 

Este enfoque es adecuado para escribir una simple prueba de cadena vacía, y luego iterar a través de los PID descubiertos.

 #!/bin/bash PROCESS=$1 PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'` if [ -z "$PIDS" ]; then echo "Process not running." 1>&2 exit 1 else for PID in $PIDS; do echo $PID done fi 

Puedes probarlo guardándolo en un archivo (llamado “en ejecución”) con permisos de ejecución (chmod + x en ejecución) y ejecutándolo con un parámetro: ./running "httpd"

 #!/bin/bash ps cax | grep httpd if [ $? -eq 0 ]; then echo "Process is running." else echo "Process is not running." fi 

¡¡¡ADVERTENCIA!!!

Tenga en cuenta que simplemente está analizando la salida de ps ax que significa que, como se ve en la salida de Linux, no se trata simplemente de hacer coincidir los procesos, sino también los argumentos pasados ​​a ese progtwig. Recomiendo ser lo más específico posible al usar este método (por ejemplo, ./running "mysql" también coincidirá con los procesos de ‘mysqld’). Recomiendo usar el which comparar con un camino completo donde sea posible.


Referencias

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm

¡DEBERÍAS saber el PID!

Encontrar un proceso tratando de hacer algún tipo de reconocimiento de patrones en los argumentos del proceso (como pgrep "mysqld" ) es una estrategia que está destinada a fallar tarde o temprano. ¿Qué pasa si tienes dos mysqld corriendo? Olvida ese enfoque. PUEDE hacerlo bien temporalmente y PUEDE funcionar durante un año o dos, pero luego sucede algo en lo que no ha pensado.

Solo el id de proceso (pid) es verdaderamente único.

Siempre almacene el pid cuando ejecute algo en el fondo. ¡En Bash esto se puede hacer con $! Bash variable. Te ahorrarás TANTO problema al hacerlo.

Cómo determinar si el proceso se está ejecutando (por pid)

Entonces ahora la pregunta es cómo saber si un pid se está ejecutando.

Simplemente hazlo:

 ps -o pid = -p 

Esto es POSIX y, por lo tanto, portátil. Devolverá el pid en sí mismo si el proceso se está ejecutando o no devolverá nada si el proceso no se está ejecutando. Estrictamente hablando, el comando devolverá una sola columna, el pid , pero dado que hemos dado un encabezado de título vacío (el material que precede inmediatamente al signo igual) y esta es la única columna solicitada, el comando ps no usará el encabezado en absoluto. . Que es lo que queremos porque facilita el análisis.

Esto funcionará en Linux, BSD, Solaris, etc.

Otra estrategia sería probar el valor de salida del comando ps anterior. Debería ser cero si el proceso se está ejecutando y distinto de cero si no es así. La especificación POSIX dice que ps debe salir> 0 si ha ocurrido un error pero no está claro para mí qué constituye ‘un error’. Por lo tanto, no estoy usando esa estrategia personalmente, aunque estoy bastante seguro de que funcionará en todas las plataformas Unix / Linux.

En la mayoría de las distribuciones de Linux, puede usar pidof (8).

Imprimirá los id. De proceso de todas las instancias en ejecución de procesos especificados, o nada si no hay instancias ejecutándose.

Por ejemplo, en mi sistema (tengo cuatro instancias de bash y una instancia de remmina ejecutándose):

 $ pidof bash remmina 6148 6147 6144 5603 21598 

En otras Unices, pgrep o una combinación de ps y grep lograrán lo mismo, como otros han señalado con razón.

La forma más sencilla es usar ps y grep:

 command="httpd" running=`ps ax | grep -v grep | grep $command | wc -l` if [ running -gt 0 ]; then echo "Command is running" else echo "Command is not running" fi 

Si su comando tiene algunos argumentos de comando, entonces también puede poner más ‘grep cmd_arg1’ después de ‘grep $ command’ para filtrar otros posibles procesos que no le interesan.

Ejemplo: muéstrame si hay algún proceso de java con el argumento proporcionado:

-Djava.util.logging.config.file = logging.properties

Esta corriendo

 ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l 

Esto debería funcionar en la mayoría de los sabores de Unix, BSD y Linux:

 PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep 

Probado en:

  • SunOS 5.10 [De ahí la PATH=... ]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • Darwin 11.2.0
  • FreeBSD 9.0-STABLE
  • Versión 4 de Red Hat Enterprise Linux ES
  • Versión 5 del servidor Red Hat Enterprise Linux

Solo una pequeña adición: si agrega el -c a ps, no necesita eliminar la línea que contiene el proceso grep -v con grep -v después. Es decir

 ps acux | grep cron 

es todo el tipeo que necesitarás en un sistema bsd-ish (esto incluye MacOSX). Puedes abandonar el -u si necesitas menos información.

En un sistema donde la genética del comando ps nativo apunta a SysV, usarías

 ps -e |grep cron 

o

 ps -el |grep cron 

para una lista que contiene más que solo pid y nombre del proceso. Por supuesto, puede seleccionar los campos específicos para imprimir utilizando la opción -o .

Combinando varias sugerencias, la versión más limpia que pude encontrar (sin grep poco confiable que desencadena partes de palabras) es:

 kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions" 

kill -0 no mata el proceso pero verifica si existe y luego devuelve verdadero; si no tiene pidof en su sistema, almacene el pid cuando inicie el proceso:

 $ mysql & $ echo $! > pid_stored 

luego en el guion:

 kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions" 

Yo uso pgrep -l httpd pero no estoy seguro de que esté presente en ninguna plataforma …
¿Quién puede confirmar en OSX?

Debe conocer el PID de su proceso.

Cuando lo ejecute, su PID se registrará en $! variable. Guarde este PID en un archivo.

Luego deberá verificar si este PID corresponde a un proceso en ejecución. Aquí hay una secuencia de comandos esqueleto completa:

 FILE="/tmp/myapp.pid" if [ -f $FILE ]; then PID=$(cat $FILE) else PID=1 fi ps -o pid= -p $PID if [ $? -eq 0 ]; then echo "Process already running." else echo "Starting process." run_my_app & echo $! > $FILE fi 

Basado en la respuesta de peterh . El truco para saber si un PID determinado se está ejecutando es en la instrucción ps -o pid= -p $PID .

Este enfoque se puede usar en caso de que los comandos ‘ps’, ‘pidof’ y rest no estén disponibles. Yo personalmente uso procfs con mucha frecuencia en mis herramientas / scripts / progtwigs.

  egrep -m1 "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3 

Pequeña explicación de lo que está pasando:

  1. -m1 – detener el proceso en el primer partido
  2. “mysqld $ | httpd $” – grep coincidirá con las líneas que terminaron en mysqld O httpd
  3. / proc / [0-9] * – bash coincidirá con la línea que comenzó con cualquier número
  4. corte: simplemente divida la salida por el delimitador ‘/’ y extraiga el campo 3

Esto imprime la cantidad de procesos cuyo nombre base es “cromo-navegador”:

 ps -e -o args= | awk 'BEGIN{c=0}{ if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets. if($1==cmd){c++} }END{print c}' cmd="chromium-browser" 

Si esto imprime “0”, el proceso no se está ejecutando. El comando asume que la ruta del proceso no contiene espacio de última hora. No he probado esto con procesos suspendidos o procesos zombie.

Probado usando gwak como la alternativa de awk en Linux.

Aquí hay una solución más versátil con algunos ejemplos de uso:

 #!/bin/sh isProcessRunning() { if [ "${1-}" = "-q" ]; then local quiet=1; shift else local quiet=0; fi ps -e -o pid,args= | awk 'BEGIN{status=1}{ name=$2 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets. if(name==cmd){status=0; if(q){exit}else{print $0}} }END{exit status}' cmd="$1" q=$quiet } process='chromium-browser' printf "Process \"${process}\" is " if isProcessRunning -q "$process" then printf "running.\n" else printf "not running.\n"; fi printf "Listing of matching processes (PID and process name with command line arguments):\n" isProcessRunning "$process" 

Aquí está mi versión. caracteristicas:

  • comprueba el nombre exacto del progtwig (primer argumento de la función). la búsqueda de “mysql” no coincidirá con la ejecución de “mysqld”
  • busca argumentos del progtwig (segundo argumento de la función)

guión:

 #!/bin/bash # $1 - cmd # $2 - args # return: 0 - no error, running; 1 - error, not running function isRunning() { for i in $(pidof $1); do cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null if [ $? -eq 0 ]; then return 0 fi done return 1 } isRunning java "-Djava.util.logging.config.file=logging.properties" if [ $? -ne 0 ]; then echo "not running, starting..." fi 

Ninguna de las respuestas funcionó para mí, así que aquí está el mío:

 process="$(pidof YOURPROCESSHERE|tr -d '\n')" if [[ -z "${process// }" ]]; then echo "Process is not running." else echo "Process is running." fi 

Explicación:

 |tr -d '\n' 

Esto elimina el retorno de carro creado por el terminal. El rest se puede explicar por esta publicación.

La siguiente función de shell, que solo se basa en los comandos y opciones estándar de POSIX, debería funcionar en la mayoría (si no en alguno) de los sistemas Unix y Linux. :

 isPidRunning() { cmd=` PATH=\`getconf PATH\` export PATH ps -e -o pid= -o comm= | awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}' ` [ -n "$cmd" ] && printf "%s is running\n%s\n\n" "$1" "$cmd" || printf "%s is not running\n\n" $1 [ -n "$cmd" ] } 

 $ isPidRunning httpd httpd is running 586 /usr/apache/bin/httpd 588 /usr/apache/bin/httpd $ isPidRunning ksh ksh is running 5230 ksh $ isPidRunning bash bash is not running 

Tenga en cuenta que se ahogará cuando pase el dudoso nombre de comando “0” y tampoco identificará procesos que tengan un espacio incrustado en sus nombres.

Tenga en cuenta también que la solución más votada y aceptada exige opciones ps no portátiles y, de forma gratuita, utiliza un shell que, a pesar de su popularidad, no está garantizado que esté presente en todas las máquinas Unix / Linux ( bash )