Verhindert, dass aktuell ausgeführte Linux-Tasks nach dem Abmelden von SSH beendet werden

18

Ich habe eine Rechenaufgabe, die einige Tage lang auf einem Linux-Server über eine SSH-Verbindung ausgeführt wird. Es befindet sich nicht im Hintergrund, daher wird die Aufgabe von der SSH-Verbindung angehalten.

Ich möchte den lokalen Computer (nicht den Server), von dem aus ich die ssh-Sitzung geöffnet habe, neu starten, aber die Task weiterhin ausführen. Ist das überhaupt möglich?

Ali
quelle

Antworten:

22

Wenn Ihre Aufgabe ist bereits ins Leben gerufen, ist es zu spät ist , *alternative Lösungen zu berücksichtigen , dass Einsatz eine zusätzliche Schicht zwischen Ihrer sshSitzung und dem Shell den Befehl ausführen, wie screen, tmux, byobu, nohupund Ähnliches.

Wenn Ihr Prozessunterstützung im Hintergrund platziert werden und vor allem nicht hängen , wenn stdoutund stderrsind nicht beschreibbar / geschlossen, können Sie es in den Hintergrund gestellt , bevor sie mit sich abzumelden ControlZund bgdann trennen sie von der Shell mit dem disownbuiltin.

z.B:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*Wie Bob bemerkte, gibt es tatsächlich mehrere hackige Möglichkeiten, eine tty-Sitzung unter Linux zu reparieren. leer, retty , injcode und neercs . Die am weitesten fortgeschrittene Version ist Reptyr, aber Sie benötigen möglicherweise Root-Rechte, damit ptrace Ihren Prozess hacken kann.

jlliagre
quelle
Ich habe Strg + Z verwendet, den Job angehalten und in den Hintergrund verschoben und dann den disownBefehl ausgeführt. Es gab zurück: Bash: Warnung: Löschen von gestopptem Job 1 mit Prozessgruppe 24876. Jetzt ist mein Job in aufgeführt ps -all, scheint aber nicht zu funktionieren (CPU-Auslastung ist 0%)
Ali
Scheint, mein Prozess ist gestoppt. Ich denke, ich hätte die Prozess-ID mit dem disownBefehl
Ali
@Ali Ich glaube, Sie haben vergessen, den Befehl bg auszuführen, um den angehaltenen Job fortzusetzen.
Jason Zhu
1
@ JasonZhu Vielen Dank für den Hinweis. Es war unklar, ob der bgBefehl im ersten Teil meiner Antwort erforderlich war. Bearbeitet
Juli
2
Wenn Sie den Befehl bg vergessen und nur den Befehl disown ausgeführt haben, sollten Sie in der Lage sein, den Prozess wieder zum Laufen zu bringen, der kill -CONTungefähr dasselbe tut wie bg.
Kasperd
5

Eine Lösung ist die Verwendung des GNU-Bildschirms . Sie könnten starten screen, Ihren Befehl ausführen und dann mit trennen C-a d. Wenn screen -rSie später erneut eine Verbindung herstellen möchten, kehren Sie zu Ihrer vorherigen Sitzung zurück.

Weitere Vorteile des Bildschirms sind die Fensterverwaltung (so dass Sie während der Ausführung Ihres Befehls zu anderen Shells wechseln können, ohne eine neue SSH-Verbindung zu benötigen) und Ihr Befehl in der aktuellen oder einer späteren Sitzung im Vordergrund bleiben kann.

Bearbeiten: Wie in den Kommentaren erwähnt, funktioniert dies nur, wenn Sie daran denken, screenvor dem Ausführen des Befehls zu starten . Wenn der Befehl bereits ausgeführt wird, benötigen Sie die Lösung von @ jlliagre.

Scott Weldon
quelle
2
tmuxist ein anderes Programm screen, mit dem Sie eine Remote-Sitzung haben können, die nicht an Ihre aktuelle SSH-Verbindung gebunden ist.
Darth Android
2
Ihre Lösung ist großartig. Es passt jedoch nicht vollständig zu meiner Frage - Ich habe nach dem aktuell ausgeführten Prozess gefragt, nicht nach einem Prozess, der in Zukunft mit ausgeführt werden soll screen.
Ali
Ah, okay. In diesem Fall müssen Sie meines Erachtens die @ jlliagre-Lösung verwenden. (Soweit ich weiß, gibt es keine Möglichkeit, einen bereits laufenden Prozess mit so etwas wie screenoder zu verbinden tmux.)
Scott Weldon
1

Eine der "Standard" -Möglichkeiten ist die Verwendung des nohupBefehls, der in der folgenden Form enthalten ist coreutils:

nohup COMMAND [ARGS] &

Aber der Befehl leitet die Ausgabe ( STDOUT& STDERRAFAIK) des Programms in eine Datei um nohup.out, was manchmal ärgerlich ist (wie das Generieren einer riesigen Protokolldatei). Vielleicht möchten Sie Ihre eigene Umleitung vornehmen oder sie nach / dev / null umleiten falls Sie es wollen.

wangguoqin1001
quelle
2
Lies erneut. Der Prozess läuft bereits .
Leichtigkeit Rennen mit Monica
Ich schäme mich nicht sorgfältig zu lesen. Es tut uns leid.
Wangguoqin1001
Tatsächlich nohupkann dafür verwendet werden. Unterbrechen Sie einfach den laufenden Prozess und senden Sie ihn an den Hintergrund ( Ctrl+ Zund führen bgSie ihn aus) nohup %1.
Mike
0

Zusätzlich nohupkönnen Sie den Prozess mit "&" und Subshell im Hintergrund starten:

Suffixieren Sie den Befehl mit & und setzen Sie ihn in Klammern

$ (thecommand args &)

Nehmen wir an, Ihr Prozess erhält die PID 1922:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

Schauen Sie, dass es nicht mit dem Shell-Prozess 11473 verbunden ist, der das ursprüngliche übergeordnete Element war. Wenn Sie also die aktuelle Shell beenden oder beenden (11473), läuft der Prozess 11922 weiter und wird von den PTS getrennt.

Versuchen Sie, die Shell zu verlassen und eine neue Shell einzugeben. Auch wenn diese Shell mit denselben Punkten verbunden ist, können Sie den Vorgang jetzt ohne Punkte sehen:

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

Ich weiß nicht, wie es in Posix heißt oder dokumentiert ist, aber ich benutze es seit 1990 in bsh, ksh und jetzt in bash.

Zuletzt können Sie den bgeingebauten Shell-Befehl verwenden:

Starten Sie einfach Ihr Programm und geben Sie STRG + Z ein, wenn Sie es anhalten oder im Hintergrund behalten möchten:

$ thecommand
^Z
[1] Stopped          thecommand

Lass es nun weiter im Hintergrund laufen:

$ bg
[1]+ thecommand &

Wenn Sie sich die Prozessinfos ansehen, gibt es noch einen übergeordneten Prozess:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

Verlassen Sie also den aktuellen Prozess. Der im Hintergrund ausgeführte Prozess ist nicht mit dem ursprünglichen übergeordneten Prozess verbunden und wird im Hintergrund ausgeführt:

$ exit

Melden Sie sich erneut an und sehen Sie sich die Prozessinformationen an:

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
Luciano
quelle