Je lance le script ci-dessous:
#!/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
La sortie est comme ::
[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
Lorsque je lance la même chose en ligne de commande, j'obtiens le statut de sortie 1:
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
Le cas est comme le vernis n'est pas installé sur le serveur. Ce script fonctionne très bien sur un serveur où le vernis est installé.
Pourquoi un statut de sortie différent lorsqu'il est exécuté à l'aide d'un script et d'une ligne de commande? Comment améliorer ce script?
Réponses:
Lorsque vous exécutez un script nommé
check_varnish_pro.sh
testréussit car un script nommé
check_
vernis est en_pro
cours d'exécution.la source
En général, c'est une mauvaise idée d'essayer l'approche simple avec
ps
etgrep
d'essayer de déterminer si un processus donné est en cours d'exécution.Vous feriez bien mieux d'utiliser
pgrep
pour cela:Voir le manuel pour
pgrep
. Sur certains systèmes (probablement pas sous Linux), vous obtenez un-q
indicateur qui correspond au même indicateur pourgrep
lequel vous vous débarrassez de la nécessité de rediriger/dev/null
. Il existe également un-f
indicateur qui effectue la correspondance sur la ligne de commande complète plutôt que sur le nom du processus uniquement. On peut également limiter la correspondance aux processus appartenant à un utilisateur spécifique utilisant-u
.L'installation
pgrep
vous donne également accès àpkill
ce qui vous permet de signaler des processus en fonction de leurs noms.De plus, s'il s'agit d'un démon de service et si votre système Unix a un moyen de l'interroger pour obtenir des informations (par exemple, s'il est opérationnel et non), alors c'est la bonne façon de le vérifier.
Sous Linux, vous avez
systemctl
(systemctl is-active --quiet varnish
retournera 0 s'il est en cours d'exécution, 3 sinon), sur OpenBSD vous avezrcctl
, etc.Passons maintenant à votre script:
Dans votre script, vous analysez la sortie de
ps ax
. Cette sortie contiendra le nom du script lui-mêmecheck_varnish_pro.sh
, qui contient évidemment la chaînevarnish
. Cela vous donne un faux positif. Vous l'auriez repéré si vous l'aviez exécuté sans-q
indicateurgrep
pendant le test.L'exécuter:
Un autre problème est que, même si vous essayez de «masquer» le
grep
processus d'être détecté pargrep
lui-même en utilisant[v]
le modèle. Cette approche échouera si vous exécutez le script ou la ligne de commande dans un répertoire contenant un fichier ou un répertoire nommévarnish
(auquel cas vous obtiendrez à nouveau un faux positif). Cela est dû au fait que le modèle n'est pas entre guillemets et que le shell effectuera la globalisation des noms de fichiers avec lui.Voir:
La présence du fichier
varnish
entraînera le remplacement du shell[v]arnish
par le nom de fichiervarnish
et vous obtenez un hit sur le modèle dans la table de processus (legrep
processus).la source
check_varnish_pro.sh
est également un facteur.@AlexP explique très succinctement ce qui se passe réellement, mais l'idée de @ Kusalananda d' utiliser
pgrep
/pkill
pour un processus critique est fortement déconseillée . De meilleures solutions comprennent:systemctl status varnishd
devrait prendre soin de cela sur une installation moderne * nix.Si, dans une circonstance malheureuse, vous n'avez pas de service disponible, vous pouvez simplement modifier le script de démarrage pour signaler le problème dès la fin du processus:
kill -0 "$pid"
.la source
systemctl
n'est presque disponible que sur Linux (AFAIK), et pas sur tous les systèmes modernes de type Unix.