Estoy ejecutando debajo del script:
#!/bin/bash
ps ax | grep -q [v]arnish
if [ $? -eq 0 ];then
echo varnish is running...
exit 0
else
echo "Critical : varnish is not running "
exit 2
fi
El resultado es como ::
[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0
Cuando ejecuto lo mismo en la línea de comando, obtengo el estado de salida como 1:
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
El caso es que el barniz no está instalado en el servidor. Este script funciona bien en un servidor donde está instalado el barniz.
¿Por qué un estado de salida diferente cuando se ejecuta usando script y línea de comando? ¿Cómo mejorar este script?
shell-script
process
ps
exit-status
prado
fuente
fuente
Respuestas:
Cuando ejecutas un script llamado
check_varnish_pro.sh
testes exitoso porque hay una secuencia de comandos llamada
check_
barniz en_pro
ejecución.fuente
En general, es una mala idea probar el enfoque simple
ps
egrep
intentar determinar si se está ejecutando un proceso determinado.Sería mucho mejor usarlo
pgrep
para esto:Vea el manual para
pgrep
. En algunos sistemas (probablemente no en Linux), se obtiene un-q
indicador que corresponde al mismo indicador para elgrep
cual se elimina la necesidad de redirigir/dev/null
. También hay una-f
bandera que realiza la coincidencia en la línea de comando completa en lugar de solo en el nombre del proceso. También se puede limitar la coincidencia a los procesos que pertenecen a un usuario específico-u
.La instalación
pgrep
también le da acceso a lopkill
que le permite señalar procesos basados en sus nombres.Además, si este es un demonio de servicio , y si su sistema Unix tiene una forma de consultar información (por ejemplo, si está en funcionamiento o no), entonces esa es la forma correcta de verificarlo.
En Linux, tiene
systemctl
(systemctl is-active --quiet varnish
devolverá 0 si se está ejecutando, 3 de lo contrario), en OpenBSD que tienercctl
, etc.Ahora a tu guión:
En su secuencia de comandos, analiza la salida de
ps ax
. Esta salida contendrá el nombre del script en sícheck_varnish_pro.sh
, que obviamente contiene la cadenavarnish
. Esto te da un falso positivo. Habría descubierto esto si lo hubiera ejecutado sin la-q
bandera durante lagrep
prueba.Ejecutándolo:
Otro problema es que aunque intenta "ocultar" el
grep
proceso para que no sea detectado porgrep
sí mismo mediante el uso[v]
del patrón. Ese enfoque fallará si ejecuta el script o la línea de comando en un directorio que tiene un archivo o directorio nombradovarnish
en él (en cuyo caso obtendrá un falso positivo, de nuevo). Esto se debe a que el patrón no está entre comillas y el shell realizará el bloqueo de nombre de archivo con él.Ver:
La presencia del archivo
varnish
hará que el shell se reemplace[v]arnish
con el nombre del archivovarnish
y obtendrá un golpe en el patrón en la tabla de procesos (elgrep
proceso).fuente
check_varnish_pro.sh
también es un factor.@AlexP explica muy sucintamente lo que realmente está sucediendo, pero la idea de @ Kusalananda de usar
pgrep
/pkill
para un proceso crítico se desaconseja . Las mejores soluciones incluyen:systemctl status varnishd
debería ocuparse de eso en una instalación moderna * nix.Si por alguna circunstancia desafortunada no tiene un servicio disponible, simplemente puede cambiar el script de inicio para informar el problema tan pronto como finalice el proceso:
kill -0 "$pid"
.fuente
systemctl
casi solo está disponible en Linux (AFAIK), y no en todos los sistemas modernos tipo Unix.