Wie man ein Python-Skript am Laufen hält, wenn ich putty schließe


19

Ich bin dabei, ein Python-Skript auf Ubuntu unter VPS auszuführen. Es ist ein maschineller Lernprozess. Nehmen Sie sich also viel Zeit, um zu trainieren. Wie kann ich Putty schließen, ohne diesen Prozess zu stoppen?


1
Auschecken nohup.
Phk

Antworten:


36

Sie haben zwei Hauptoptionen:

  1. Führen Sie den Befehl mit nohup. Dadurch wird die Verbindung zu Ihrer Sitzung getrennt und die Verbindung nach dem Trennen der Verbindung fortgesetzt:

    nohup pythonScript.py

    Beachten Sie, dass die Standardausgabe des Befehls an eine aufgerufene Datei angehängt wird, es nohup.outsei denn, Sie leiten sie um ( nohup pythonScript.py > outfile).

  2. Verwenden Sie einen Screen-Multiplexer wie tmux. Auf diese Weise können Sie die Verbindung zum Remotecomputer trennen. Wenn Sie das nächste Mal eine Verbindung herstellen, befinden Sie sich bei einem tmux attacherneuten Start in genau derselben Sitzung. Der Befehl wird weiterhin ausgeführt (er wird fortgesetzt, wenn Sie sich abmelden), und Sie können die Befehle stdout und stderr so anzeigen, als ob Sie sich nie abgemeldet hätten:

    tmux 
    pythonScript.py

    Sobald Sie das gestartet haben, schließen Sie einfach das PuTTY-Fenster. Am nächsten Tag tmux attacherneut eine Verbindung herstellen, erneut ausführen und Sie sind wieder da, wo Sie begonnen haben.


4
Alternativen zu 1 & 2: 1. disown2.screen
heemayl

Erwähnenswert byobuist auch ein Wrapper um tmux oder screen.
bli

2

Das screenfür alle Linux-Distributionen verfügbare Tool unterstützt dies.

Um es zu installieren, führen Sie es apt-get install screenfür deb-basierte Linux-Distributionen dnf install -y screenoder yum install -y screenfür RPM-basierte aus.

Benutzen:

$ screen

Eine neue Shell wird gestartet. In dieser Shell können Sie Ihr Python-Skript starten. Dann können Sie die Taste Ctrl+ Shift+ Adann D. Dadurch wird Ihr Terminal von der Shell getrennt, auf der Ihr Skript ausgeführt wird. Außerdem läuft das Skript noch darin.

Um zu sehen, wie Ihr Skript ausgeführt wird, können Sie anrufen screen -r. Dadurch wird Ihr Terminal mit dem Python-Skript, das Sie im Hintergrund ausgeführt haben, wieder mit der Shell verbunden.

UPD: Wie Fox bereits erwähnt hat, funktioniert screen schlecht mit systemd, aber wir können systemd verwenden, um das Skript zu starten, wie es im offiziellen Beispiel heißt .

Wenn Ihr Skript beispielsweise von gestartet wird /usr/bin/myPythonScript, können Sie wie folgt eine Systemd-Unit-Datei erstellen.

$ cat /etc/systemd/system/myPythonScript.service

[Unit]
Description=MyPythonScript

[Service]
ExecStart=/usr/bin/myPythonScript

[Install]
WantedBy=multi-user.target

Dann können Sie dieses Skript starten # systemctl daemon-reload # systemctl start myPythonScript

Wenn Sie möchten, dass dieses Skript beim Systemstart automatisch gestartet wird -

# systemctl enable myPythonScript

Sie können jederzeit anzeigen, wie Ihr Skript ausgeführt wird

# systemctl status myPythonScript

Anzeige können Sie Protokolle Ihres Skripts überprüfen

# journalctl -u myPythonScript -e


Beachten Sie, dass screendies systemdin der Standardkonfiguration nicht gut funktioniert . Ich weiß nicht, ob Ubuntu verwendet systemd, aber das Verhalten und die Problemumgehung sollten in Ihrer Antwort erwähnt werden
Fox

1

Die meisten Prozesse können durch Umleiten von stdout, stderr und stdin (nicht alle Deskriptoren müssen immer umgeleitet werden) und Verwendung des Steueroperators getäuscht werden &.

Sehen Sie, das ping example.com 1>/dev/null &macht den Job.

Natürlich sind einige Programme anspruchsvoller und erfordern Lösungen wie @terdon, aber es ist gut zu wissen und zu verwenden, was am besten passt.

EDIT: wie in geschrieben dieser Antwort tötet systemdProzesse beim Abmelden. Einige Versionen von systemdKill-Prozessen werden standardmäßig beim Abmelden ausgeführt, andere nicht. Dieses Verhalten kann durch Ändern von /etc/systemd/logind.conf durch Festlegen der folgenden Option geändert werden. Wie bereits geschrieben, werden möglicherweise auch einige Probleme mit den Lösungen von @ terdon behoben.

von man logind.conf:

KillUserProcesses=

Nimmt ein boolesches Argument an. Konfiguriert, ob die Prozesse eines Benutzers beendet werden sollen, wenn sich der Benutzer abmeldet. Wenn true, werden die der Sitzung entsprechende Bereichseinheit und alle Prozesse in diesem Bereich beendet. Wenn false, wird der Bereich "aufgegeben" (siehe systemd.scope (5)), und Prozesse werden nicht abgebrochen. Der Standardwert ist "Ja", siehe jedoch die Optionen KillOnlyUsers=und KillExcludeUsers=unten.

Zusätzlich zu den Sitzungsprozessen kann der Benutzerprozess unter der Benutzerverwaltungseinheit user @ .service ausgeführt werden. Abhängig von den Einstellungen für die Verweildauer können Benutzer damit Prozesse unabhängig von ihren Anmeldesitzungen ausführen. Siehe die Beschreibung enable-lingerin loginctl(1).

Beachten Sie, dass durch die Einstellung KillUserProcesses=yesTools wie screen(1) und tmux(1) beschädigt werden, sofern sie nicht aus dem Sitzungsbereich verschoben werden. Siehe Beispiel in systemd-run(1).

Lesen Sie die verknüpfte Antwort, um mehr zu erfahren.


1
Dies schickt den Prozess einfach in den Hintergrund. Das OP möchte sich von einer Remote-SSH-Sitzung trennen und den Vorgang fortsetzen können. Dies hilft in dieser Situation nicht weiter, da das Beenden der Remotesitzung den Befehl auch dann beendet, wenn er sich im Hintergrund befindet.
Terdon

@terdon hast du geprüft ob mein beispiel funktioniert? Ich habe geprüft und es funktioniert für einige Befehle, wie ich in meiner Antwort geschrieben habe.
Styropor fliegen

Ja, ich habe geprüft und ja, ich habe gesehen, dass der Befehl manchmal fortgesetzt wird. Ich habe jedoch sehr oft gesehen, dass der Befehl nicht mehr ausgeführt wird, es sei denn, Sie können genau erläutern, welche Befehle ausgeführt werden, oder Sie können im Voraus wissen, ob der Befehl ausgeführt wird oder nicht. Dies ist nicht sehr nützlich. In der Tat ist das von Ihnen angegebene Beispiel bei einem Test, bei dem ich gerade eine Verbindung von meinem Arch zu einem entfernten Ubuntu-System hergestellt habe, fehlgeschlagen.
Terdon

@terdon lustig, ich habe dies auf lokalen ArchLinux-Verbindung zu Remote-PLD überprüft. Die einzige Regel, die immer funktioniert, lautet: " isatty()Wird das Programm verwendet und beendet, wenn dies nicht der Fall ist?"
Styropor fliegen

Das könnte eine eigene Frage verdienen. Ich weiß, ich brauchte früher immer nichts, und irgendwann änderte sich etwas, und manchmal tat ich es nicht. Ich kann jedoch nicht sehen, wie das isatty sein könnte, wenn Sie die übergeordnete Shell verlassen, sollte dies auch das Kind töten. Aber manchmal schon. Ich vermute, es muss irgendwie konfigurierbar sein.
Terdon
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.