it-swarm.com.de

So starten Sie das Skript Python automatisch neu, wenn es beendet wird oder stirbt

Ich führe mein Python Skript im Hintergrund auf meinem Ubuntu-Rechner (12.04) so ​​aus -

Nohup python testing.py > test.out &

Nun könnte es möglich sein, dass mein oben genannter Python script Irgendwann aus irgendeinem Grund sterben kann.

Ich denke also, eine Art cron agent Im Bash-Shell-Skript zu haben, die mein oben genanntes Python -Skript automatisch neu starten kann, wenn es aus irgendeinem Grund beendet wird.

Ist das möglich? Wenn ja, wie lässt sich ein solches Problem am besten lösen?

PDATE :

Nach dem Erstellen der testing.conf - Datei wie folgt -

chdir /tekooz
exec python testing.py
respawn

Ich habe den Sudo-Befehl ausgeführt, um ihn zu starten, aber ich kann nicht sehen, dass dieser Prozess mit ps ax ausgeführt wird.

[email protected]:/bezook# Sudo start testing
testing start/running, process 27794
[email protected]:/bezook# ps ax | grep testing.py
27806 pts/3    S+     0:00 grep --color=auto testing.py

Irgendeine Idee, warum px ax mir nichts zeigt? Und wie überprüfe ich, ob mein Programm läuft oder nicht?

Dies ist mein python Skript -

#!/usr/bin/python
while True:
    print "Hello World"
    time.sleep(5)
34
arsenal

Unter Ubuntu (bis 14.04, 16.04 und höher systemd) kann upstart verwendet werden, besser als ein Cron-Job. Sie fügen ein Konfigurationssetup in /etc/init Ein und stellen sicher, dass Sie respawn angeben

Es könnte eine minimale Datei /etc/init/testing.conf Sein (bearbeiten als root):

chdir /your/base/directory
exec python testing.py
respawn

Und Sie können mit /your/base/directory/testing.py Testen:

from __future__ import print_function

import time

with open('/var/tmp/testing.log', 'a') as fp:
    print(time.time(), 'done', file=fp)
    time.sleep(3)

und beginnen mit:

Sudo start testing

und folge was passiert (in einem anderen Fenster) mit:

tail -f /var/tmp/testing.log

und hör auf mit:

Sudo stop testing

Sie können auch [start on][2] Hinzufügen, damit der Befehl beim Booten des Systems gestartet wird.

24
Zelda

Sie könnten auch einen Shell-orientierten Ansatz wählen. Lassen Sie Ihr cron nach Ihrem Skript suchen und es neu starten, wenn es stirbt.

  1. Erstellen Sie eine neue Crontab, indem Sie crontab -e. Dadurch wird ein Fenster Ihres bevorzugten Texteditors geöffnet.

  2. Fügen Sie diese Zeile der gerade geöffneten Datei hinzu

    */5 * * * * pgrep -f testing.py || Nohup python /home/you/scripts/testing.py > test.out
    
  3. Speichern Sie die Datei und beenden Sie den Editor.

Sie haben gerade ein neues crontab erstellt, das alle 5 Minuten ausgeführt wird und Ihr Skript startet, sofern es nicht bereits ausgeführt wird. Siehe hier für ein nettes kleines Tutorial zu cron. Die offiziellen Ubuntu-Dokumente zu cron sind hier .

Der tatsächlich ausgeführte Befehl ist pgrep, der laufende Prozesse nach der in der Befehlszeile angegebenen Zeichenfolge durchsucht. pgrep foo sucht nach einem Programm mit dem Namen foo und gibt dessen Prozesskennung zurück. pgrep -f lässt es die gesamte Befehlszeile durchsuchen, die zum Starten des Programms verwendet wird, und nicht nur den Programmnamen (nützlich, da dies ein python -Skript) ist.

Das || Symbol bedeutet "dies tun, wenn der vorherige Befehl fehlgeschlagen ist". Wenn Ihr Skript nicht ausgeführt wird, schlägt pgrep fehl, da nichts gefunden wird und Ihr Skript gestartet wird.

21
terdon

Es gibt verschiedene Möglichkeiten, Prozesse unter UNIX/Linux zu überwachen und neu zu starten. Einer der ältesten ist ein "Respawn" -Eintrag in/etc/inittab ... wenn Sie das alte SysV-Init-System verwenden. Eine andere Methode ist die Verwendung des Supervisor-Daemons aus dem Paket daemontools von DJ Bernstein. Andere Optionen sind die Verwendung von Funktionen in Ubuntu upstart ... oder systemd oder anderen.

Sie können sich jedoch alternatives init und insbesondere den Daemon Python Code für Pardus: mudur ) ansehen.

Wenn Sie sich für einen Cron-Job (und die Behandlung von PID-Dateien) entscheiden, lesen Sie diesen PEP 314 und verwenden Sie möglicherweise dessen Referenzimplementierung.

Wie ich in meinen anderen Kommentaren angedeutet habe, ist eine robuste Handhabung von PID-Dateien schwierig. Es ist anfällig für Rennen und Eckfälle. Es wird schwieriger, wenn die Möglichkeit besteht, dass Ihre PID-Datei auf einem NFS oder einem anderen vernetzten Dateisystem landet (ein Teil der Atomarität garantiert, dass Sie mit der Semantik der Dateiverwaltung auf richtigen lokal UNIX/Linux-Dateisystemen arbeiten zum Beispiel bei einigen Versionen und Implementierungen von NFS). Auch die Semantik beim Sperren von Dateien unter UNIX kann schwierig sein. (Wird eine flock - oder fcntl -Sperre in Ihrem Zielbetriebssystem sofort freigegeben, wenn der Prozess, der sie enthält, beispielsweise mit SIGKILL beendet wird?).

6
Jim Dennis

Sie können das Testprogramm die Ausgabe mithilfe einer Befehlszeilenoption umleiten lassen und dann ein einfaches Skript python] verwenden, um das Programm auf unbestimmte Zeit neu zu starten:

import subprocess

while True:
    try:
        print subprocess.check_output(['python', 'testing.py'])
    except KeyboardInterrupt:
        break

sie können dieses Programm in den Hintergrund stellen. Wenn Sie aufhören möchten, ziehen Sie es einfach in den Vordergrund und beenden Sie es.

6
Anthon

Sie sollten dies nicht wirklich für die Produktion verwenden, aber Sie könnten:

#!/bin/sh

while true; do
  Nohup python testing.py >> test.out
done &

Wenn aus irgendeinem Grund der Prozess python beendet wird), wird die Shell-Schleife fortgesetzt und neu gestartet, wobei wie gewünscht an die Datei .out Angehängt wird. Fast kein Overhead und sehr wenig Zeit erforderlich installieren.

6
K3---rnc

Sie können auch monit oder Prozessüberwachung mit ps-watcher verwenden

Monit ist ein Open Source-Dienstprogramm zum Verwalten und Überwachen von Prozessen, Programmen, Dateien, Verzeichnissen und Dateisystemen auf einem UNIX-System. Monit führt automatische Wartungs- und Reparaturarbeiten durch und kann in Fehlersituationen sinnvolle kausale Aktionen ausführen.

Hier ist ein Beispiel für Ihr Szenario:

check process myprocessname
        matching "myprocessname"
        start program = "Nohup /usr/bin/python /path/testing.py > /tmp/test.out &"
        stop program = "/usr/bin/killall myprocessname"

Schauen Sie sich Monit-Beispiele an

3
Rahul Patil

Sie benötigen einen Supervisor, Sie können Supervisor verwenden. Es ist python-basierter Supervisor, daher bei Bedarf einfach zu ändern.

Die Steuerung erfolgt mit Dateien mit INI-Dateisyntax.

1
user41123

In meinem Fall wollte ich als schnelle Lösung mein Programm am Laufen halten, wenn es mit einem Fehler beendet wurde oder getötet wurde. Andererseits wollte ich die Ausführung stoppen, wenn das Programm korrekt beendet wurde (Rückkehrcode = 0)

Ich habe es auf Bash getestet. Es sollte in jeder anderen Shell gut funktionieren

#!/bin/sh

echo ""
echo "Use: $0 ./instagram.py"
echo ""

echo "Executing $1 ..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done)
0
user9869932

Für Terdons Antwort: pgrep -f testing.py wird gemäß den Kommentaren in hier niemals false zurückgeben:

Ich denke, das Problem ist, dass cron eine Shell erzeugt, um Ihren Befehl auszuführen, und die Argumente dieser Shell von pgrep abgeglichen werden, da Sie -f verwenden

Für Matts Antwort: pgrep -f testing.py ist nutzlos seit pgrep python stimmt mit jedem laufenden Python Skript überein. Wenn also zwei Python Skript Cronjob), wird der zweite Cronjob niemals ausgeführt.

Und dann habe ich die Lösung gefunden, um pgrep -f testing.py im Kommentar hier: https://askubuntu.com/questions/1014559/running-pgrep-in-a-crontab?noredirect=1&lq=1

Mein Cron für die Ausführung von zwei Python Skripten:

* * * * * pgrep -f '^/usr/bin/python36 /home/ec2-user/myscript1\.py' || Nohup /usr/bin/python36 /home/ec2-user/myscript1.py

0 * * * * pgrep -f '^/usr/bin/python36 /home/ec2-user/myscript2\.py' || Nohup /usr/bin/python36 /home/ec2-user/myscript2.py
0
Frank

Terdons Antwort hat bei mir nicht funktioniert, weil pgrep -f testing.py scheiterte nie. Es würde die PID für den Cron-Job abrufen (wegen der Option -f). Ohne die Option -f findet pgrep testing.py jedoch nicht, da es keinen Prozess namens testing.py gibt.

Meine Lösung dafür war zu ändern

pgrep -f testing.py

zu

pgrep -f testing.py | pgrep python

dies bedeutet, dass der vollständige Crontab-Job wäre:

*/5 * * * * pgrep -f testing.py | pgrep python || Nohup python /home/you/scripts/testing.py > test.out
0
Matt