web-dev-qa-db-fra.com

Linux Script pour vérifier si le processus est en cours d'exécution et agir sur le résultat

J'ai un processus qui échoue régulièrement et commence parfois des instances en double.

Lorsque j'exécute: ps x |grep -v grep |grep -c "processname", Je recevrai: 2, Ce processus est normal car le processus s'exécute avec un processus de récupération.

Si j'obtiens 0 Je voudrai démarrer le processus si j'obtiens: 4 Je voudrai arrêter et redémarrer le processus

Ce dont j'ai besoin, c'est d'une manière de prendre le résultat de ps x |grep -v grep |grep -c "processname"

Puis configurez une fonction simple à 3 options

ps x |grep -v grep |grep -c "processname"
if answer = 0 (start process & write NOK & Time to log /var/processlog/check)
if answer = 2 (Do nothing & write OK & time to log /var/processlog/check)
if answer = 4 (stot & restart the process & write NOK & Time to log /var/processlog/check)

Le processus est arrêté avec killall -9 process Le processus est démarré avec process -b -c /usr/local/etc

Mon principal problème est de trouver un moyen d'agir sur le résultat de ps x |grep -v grep |grep -c "processname".

Idéalement, j'aimerais que le résultat de ce grep devienne une variable dans le script avec quelque chose comme:

process=$(ps x |grep -v grep |grep -c "processname")

Si possible.

32
linuxnoob

Programmes pour surveiller si un processus sur un système est en cours d'exécution.

Le script est stocké dans crontab et s'exécute une fois par minute.

Cela fonctionne avec les processus non en cours d'exécution et les processus multiples:

#! /bin/bash

case "$(pidof amadeus.x86 | wc -w)" in

0)  echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt
    /etc/amadeus/amadeus.x86 &
    ;;
1)  # all ok
    ;;
*)  echo "Removed double Amadeus: $(date)" >> /var/log/amadeus.txt
    kill $(pidof amadeus.x86 | awk '{print $1}')
    ;;
esac

0 Si le processus n’est pas trouvé, redémarrez-le.
1 Si le processus est trouvé, tout va bien.
* Si le processus est exécuté à 2 ou plus, tuez le dernier.


Une version plus simple. Cela ne fait que tester si le processus est en cours d’exécution et, le cas échéant, le redémarrer.

Il teste simplement le drapeau de sortie $? du programme pidof. Ce sera 0 du processus est en cours d'exécution et 1 si non.

#!/bin/bash
pidof  amadeus.x86 >/dev/null
if [[ $? -ne 0 ]] ; then
        echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt
        /etc/amadeus/amadeus.x86 &
fi

Et enfin, un one-liner

pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus:     $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &

cccam oscam

66
Jotne

J'ai adopté la solution @Jotne et fonctionne parfaitement! Par exemple pour le serveur Mongodb dans mon NAS

#! /bin/bash

case "$(pidof mongod | wc -w)" in

0)  echo "Restarting mongod:"
    mongod --config mongodb.conf
    ;;
1)  echo "mongod already running"
    ;;
esac
8
Tirias

J'ai adopté votre script pour ma situation Jotne.

#! /bin/bash

logfile="/var/oscamlog/oscam1check.log"

case "$(pidof oscam1 | wc -w)" in

0)  echo "oscam1 not running, restarting oscam1:     $(date)" >> $logfile
    /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
    ;;
2)  echo "oscam1 running, all OK:     $(date)" >> $logfile
    ;;
*)  echo "multiple instances of oscam1 running. Stopping & restarting oscam1:     $(date)" >> $logfile
    kill $(pidof oscam1 | awk '{print $1}')
    ;;
esac

Pendant que je testais, j'ai rencontré un problème .. J'ai démarré 3 processus supplémentaires d'oscam1 avec cette ligne: /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 qui m'a laissé 8 processus pour oscam1. Le problème est le suivant. Lorsque je lance le script, il ne tue que 2 processus à la fois.

Autre que killall -9 oscam1 suivi par /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1, dans *)est-il un meilleur moyen de tuer tout en dehors du processus original? Donc, il n'y aurait aucun temps d'arrêt?

4
linuxnoob

Si vous avez changé awk '{print $ 1}' en '{$ 1 = ""; print $ 0} ', vous obtiendrez tous les processus sauf le premier. Cela commencera par le séparateur de champs (un espace en général) mais je ne me souviens pas de l’attentat envers tous. Alors:

#! /bin/bash

logfile="/var/oscamlog/oscam1check.log"

case "$(pidof oscam1 | wc -w)" in

0)  echo "oscam1 not running, restarting oscam1:     $(date)" >> $logfile
    /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
    ;;
2)  echo "oscam1 running, all OK:     $(date)" >> $logfile
    ;;
*)  echo "multiple instances of oscam1 running. Stopping & restarting oscam1:     $(date)" >> $logfile
    kill $(pidof oscam1 | awk '{ $1=""; print $0}')
    ;;
esac

Il est à noter que la route pidof semble fonctionner correctement pour les commandes sans espaces, mais vous voudrez probablement revenir à une chaîne basée sur ps si vous recherchez, par exemple, un script python nommé myscript. qui a montré sous ps comme

racine 22415 54.0 0,4 89116 79076 pts/1 S 16:40 0:00/usr/bin/python/usr/bin/myscript

Juste un FYI

0
Kris Long