scripts script programacion español ejemplos ejecutar comandos comando basicos linux bash shell unix process

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



scripts bash ejemplos (13)

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?


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 answer de peterh . El truco para saber si un PID determinado se está ejecutando es en la instrucción ps -o pid= -p $PID .


¡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 <pid>

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.


Aquí está mi versión. caracteristicas:

  • comprueba el nombre exacto del programa (primer argumento de la función). la búsqueda de "mysql" no coincidirá con la ejecución de "mysqld"
  • busca argumentos del programa (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


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"


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.


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

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

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"


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


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 )


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]*''

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


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 <field,field,...> .


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