La forma "adecuada" de probar si un servicio se ejecuta en un script


98

Mi problema:

Estoy escribiendo un script bash y en él me gustaría verificar si se está ejecutando un servicio determinado.

Sé cómo hacer esto manualmente, con $ service [service_name] status.

Pero (especialmente desde el cambio a systemd) que imprime un montón de texto que es un poco complicado de analizar. Supuse que hay un comando hecho para scripts con salida simple o un valor de retorno que puedo verificar.

Pero buscar en Google solo produce una tonelada de resultados de "Oh, solo ps aux | grep -v grep | grep [service_name]". Esa no puede ser la mejor práctica, ¿verdad? ¿Qué sucede si se está ejecutando otra instancia de ese comando, pero ninguna iniciada por el script de inicio SysV?

¿O debería callarme y ensuciarme las manos con un poco de pgrep?

Respuestas:


141

systemctltiene un is-activesubcomando para esto:

systemctl is-active --quiet service

saldrá con el estado cero si serviceestá activo, de lo contrario no será cero, por lo que es ideal para scripts:

systemctl is-active --quiet service && echo Service is running

Si omite --quiet, también mostrará el estado actual en su salida estándar.

Como señaló don_crissti , algunas unidades pueden estar activas aunque no se esté ejecutando nada para proporcionar el servicio: las unidades marcadas como "RemainAfterExit" se consideran activas si salen con éxito, la idea es que proporcionan un servicio que no necesita un demonio ( por ejemplo , configuran algún aspecto del sistema). Sin embargo, las unidades que involucran demonios solo estarán activas si el demonio aún se está ejecutando.


Cuidado con los servicios de un disparo. Son únicos inactiveo activatingambos systemctl statusy systemctl is-activesalen con 3. (a partir de systemd-241 ) Solución:systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@Alois Me pregunto qué tipo de escenarios ha encontrado en los que le gustaría considerar un servicio de un solo disparo activo; ¿Tienes un ejemplo?
Stephen Kitt

Claro, @StephenKitt. La herramienta foohace algo al sistema que implica reiniciar y utiliza un servicio de una sola vez, por ejemplo, foo_cleanupen el próximo inicio para limpiar las cosas. Estoy probando esto (mi script también está programado como un servicio) y quiero recopilar errores después, pero ¿cuándo es después (vsauce music)? Bueno, uno de los criterios es que foo_cleanupha terminado ("dejó de estar activo").
Alois Mahdal

Puede valer la pena señalar que 'es fallido' también es una opción, y es útil si necesita realizar una acción basada en un servicio no iniciado.
Phill Healey

33

systemctltiene un modo adecuado para secuencias de comandos; use en showlugar de statusy agregue las opciones -p/ --propertiesy --valuepara obtener solo la salida que desea.

Aquí hay un ejemplo (de un sistema Ubuntu 17.04):

$ systemctl show -p SubState --value NetworkManager
running

Correr (o de otro modo) es a SubState. Si desea saber si un servicio está activo, use la propiedadActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

Notas de man:

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".

2
+1 para respuesta sofisticada. especifique amablemente las distribuciones que aceptarán la --versionopción con systemctl.
SK Venkat

11

Como complemento a la respuesta de Zanna, la --valueopción para systemctl showse ha introducido con la versión 230 de systemd . Por lo tanto, es posible que no esté disponible en ciertas distribuciones como Debian Jessie.

En este caso, se puede emular la opción usando sed:

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running

1
+1 para señaló la versión de introducción --value & distro que no funcionará.
SK Venkat

3

Esto me resulta útil para la ejecución de la línea de comandos o si está creando scripts.

Copiado de @StephenKitt

Esto verificará si el servicio está inactivo y reiniciará el servicio.

systemctl is-active --quiet <service name> || <service name> restart

la ||no comprueba si el valor de retorno de systemctl no es cero sentido si no es activo como se ha explicado por el autor.


También puede usar `is-failure´ para probar si es necesario reiniciar. Parece un poco más intuitivo para reiniciar un servicio fallido.
Phill Healey

Sí, pero para mí ... quería practicar y asumir que todo está funcionando cuando no lo está. así que puedo ir a verificar otras cosas con él. simplemente si solo desea verificar si no se está ejecutando, entonces 'es fallido' es una opción legítima. :)
asterisco

3


Llego demasiado tarde a la fiesta, sin embargo, el uso de systemctl está activo junto con &&y ||en este script no será el caso todo el tiempo. El siguiente es uno que utilicé para tomcat, pero puedo usarlo en el método para tomar argumentos y pasar el nombre del servicio como argumentos si tiene que verificar múltiples servicios pero está fuera de alcance aquí.

STATUS=`systemctl is-active tomcat.service`
  if [[ ${STATUS} == 'active' ]]; then
    echo "Execute your tasks ....."
  else 
    echo " Service not running.... so exiting "  
    exit 1  
  fi

Así es como hice uso de ... Simplemente compartiendo el mío.

y por la simplicidad y las cosas fáciles, siga a otros explicados aquí:

systemctl -q is-active tomcat.service  && echo "Tomcat Runnung" || echo "Service is not running at all "

¿Cómo es eso mejor que simplemente if systemctl is-active --quiet tomcat.service? Además, [[no es shell estándar.
Toby Speight

@TobySpeight Necesitas leer mi publicación un poco más como mencioné en mi publicación "Así es como hice uso de ... Simplemente compartiendo la mía". Nunca dije, es un uso de shell estándar, si lo haces con un solo soporte, se convertirá entonces, pero eso está fuera de alcance aquí. Además, a continuación menciono el uso fácil de una sola línea para hacerlo usando &&y ||.
SAGAR Nair

2

En lugar de usar el comando sed como en la respuesta de Oxmel, es suficiente cut -d'=' -f 2para todo tipo de propiedades consultadas:

por ejemplo:

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running

Eso es genial, pero realmente necesitas dar una explicación de lo que hacen esos comandos.
Phill Healey

-1

Acabo de encontrar este pequeño guión genial:

#!/bin/bash
service=replace_me_with_a_valid_service

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
  echo "$service is running!!!"
else
  /etc/init.d/$service start
fi

Fuente


No todos los servicios tienen un ejecutable con el mismo nombre, y cualquier usuario podría estar ejecutando un comando que coincida accidentalmente; esta es una receta para el desastre.
Toby Speight
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.