web-dev-qa-db-fra.com

Script shell pour relancer un processus s'il génère un texte spécifique

J'ai un programme python qui, de temps en temps, se bloque avec un certain nombre d'exceptions différentes, généralement en raison de problèmes de réseau. Le seul moyen de le faire fonctionner est de le redémarrer. Comment pourrais-je écrire un script Shell pour exécuter le processus, vérifier en permanence si l'une des sorties dit Error et si ainsi mettre fin au processus et relancer la commande (appelons-le ./command.sh)?

Ce serait bien que ce soit dans une autre langue (python/Perl, etc.).

3
Callum Rogers

Puisque python se ferme avec un code de retour! = 0 lorsqu'il lève une exception, vous pouvez simplement exécuter ce script Shell:

while ! ./command.sh ; do : ; done

Bien sûr, si vous voulez juste exécuter la commande tout le temps, écrivez simplement:

while true ; do ./command.sh ; done

(cela suppose que ./command.sh ne pointe pas et ne quitte pas)

3
jmuc

J'ai fait quelque chose de similaire pour récupérer Ted (Torrent Episode Downloader) de ses crashs habituels. Ci-dessous, le script que j'ai utilisé. Je l'expliquerai dans les modifications ultérieures au fur et à mesure.

Comment ça marche?

Ted a un fichier journal. Puisqu'il vérifie les nouveaux épisodes toutes les demi-heures, il y a un horodatage dans ce journal, qui ne date pas de plus d'une demi-heure. Bien sûr, l'horodatage n'est pas là si Ted s'est écrasé entre-temps.

Comment cela pourrait vous aider

Vous pouvez rediriger la sortie de votre programme problématique dans un fichier. Ecrivez un script similaire au mien, qui vérifie ce fichier. S'il y trouve la chaîne incorrecte, redémarre l'application (et supprime le fichier de sortie). Vous pouvez exécuter le script dans une boucle sans fin ou utiliser cron. J'ai choisi d'utiliser cron afin d'avoir moins de pollution liée aux processus et que les contrôles n'aient pas à être incroyablement fréquents de toute façon.

#!/bin/bash
# indent-mode: spaces, indentsize: 4, encoding: utf-8
# © 2011 [email protected].
# Use permitted under MIT license:
# http://www.opensource.org/licenses/mit-license.php (NO WARRANTY IMPLIED)

teddir='/home/confus/ted'   # Location of the ted executable
logpath='/home/confus/.Torrent Episode Downloader/log.txt' # Location of ted's log

# Get the process id for ted so it can be killed later
pid=$(lsof "$teddir/ted.jar" | grep -m1 Java )
set -- $pid
pid=$2
echo "Ted is running unter pid: $pid."

# Check if the log is recent
search=$(date "+%b %d, %Y @ {0,1}%l:[0-9]{2} %p")
search=$(cat "$logpath" | grep -oE "$search")

# If ted is running and the log is not recent, kill crashed process and
#+restart it.
if [ -n "$pid" ] && [ ! -n "$search" ]; then
    echo "Killig $pid."
    kill "$pid" || exit 1
    echo "Restarting ted..."
    cd "$teddir"
    /usr/bin/Java -jar ted.jar noTray
fi

exit 0

Dans mon cas, il y avait toujours un processus actif pour Ted après le crash, mais Ted ne faisait rien. Tue son processus, alors vous pouvez bien sûr ignorer les pid-Parts.

P.S. Ce pourrait être ou ne pas être un mauvais morceau de code. Il existe peut-être une bien meilleure solution, mais cela fonctionne et je l'ai mis en place très rapidement.

2
con-f-use