Einen Linux-Prozess laufen lassen, nachdem ich mich abgemeldet habe

142

Ich verbinde mich über SSH mit einem Linux-Computer und versuche, ein schweres Bash-Skript auszuführen, das Dateisystemoperationen ausführt. Es wird erwartet, dass es stundenlang läuft, aber ich kann die SSH-Sitzung wegen Internetverbindungsproblemen nicht offen lassen.

Ich bezweifle, dass das Ausführen des Skripts mit dem Hintergrundoperator, dem kaufmännischen Und ( &) , das Problem lösen wird, da ich es ausprobiert habe und später feststellte, dass der Vorgang nicht abgeschlossen wurde. Wie kann ich mich abmelden und den Prozess am Laufen halten?

doc_id
quelle

Antworten:

135

Die beste Methode ist, den Prozess in einem Terminal-Multiplexer zu starten. Alternativ können Sie dafür sorgen, dass der Prozess das HUP-Signal nicht empfängt.


Ein Terminal-Multiplexer stellt "virtuelle" Terminals bereit, die unabhängig vom "realen" Terminal laufen (tatsächlich sind alle Terminals heutzutage "virtuell", aber das ist ein anderes Thema für einen anderen Tag). Das virtuelle Terminal läuft weiter, auch wenn Ihr reales Terminal mit Ihrer SSH-Sitzung geschlossen wird.

Alle vom virtuellen Terminal aus gestarteten Prozesse laufen mit diesem virtuellen Terminal weiter. Wenn Sie sich wieder mit dem Server verbinden, können Sie sich wieder mit dem virtuellen Terminal verbinden, und alles wird so, als wäre nichts passiert, außer der Zeit, die vergangen ist.

Zwei beliebte Terminal-Multiplexer sind screen und tmux .

Bildschirm hat eine steile Lernkurve. Hier ist ein gutes Tutorial mit Diagrammen, die das Konzept erläutern: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


Das HUP- Signal (oder SIGHUP) wird vom Terminal an alle untergeordneten Prozesse gesendet, wenn das Terminal geschlossen wird. Die übliche Aktion beim Empfang von SIGHUP ist das Beenden. Wenn Ihre SSH-Sitzung getrennt wird, werden alle Ihre Prozesse beendet. Um dies zu vermeiden, können Sie dafür sorgen, dass Ihre Prozesse kein SIGHUP erhalten.

Zwei einfache Methoden sind nohupund disown.

Weitere Informationen zu Funktionsweise nohupund Funktionsweise finden disownSie in dieser Frage und Antwort: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Hinweis: Obwohl die Prozesse weiterhin ausgeführt werden, können Sie nicht mehr mit ihnen interagieren, da sie keinem Terminal mehr zugeordnet sind. Diese Methode eignet sich hauptsächlich für lange laufende Batch-Prozesse, bei denen nach dem Start keine Benutzereingaben mehr erforderlich sind.

Lesmana
quelle
3
Diese Antwort gefällt mir, da sie eine Lösung für interaktive und nicht interaktive Situationen bietet. Im interaktiven Fall stehen screenIhnen viel mehr Optionen zur Verfügung. Wenn Sie jedoch die authorized_keysMöglichkeit verwenden, ein Skript von einem Remotestandort aus auszuführen ssh, ist diese nohupOption eine einfache Möglichkeit, mit dem Skript Prozesse zu starten, die länger dauern als die sshSitzung, in der sie gestartet wurden .
Mark Booth
1
@rahmanisback - Denken Sie daran, dass Sie Ihre akzeptierte Antwort jederzeit ändern können. Nur weil die Antwort von EricA bisher am höchsten bewertet wurde, heißt das noch lange nicht, dass es die beste Antwort für Sie ist. In der Tat kann es durchaus dazu führen, dass mehr Menschen sie als gute Antwort bewerten.
Mark Booth
3
* Husten * tmuxisbetter * Husten *
crasic
3
tmux > screen. Probieren Sie es aus, Sie werden nie zurückkehren.
h0tw1r3
1
@TheLQ - byobu ist GNU Screen. Sie verwenden immer noch den Bildschirm, nur mit einem hochgradig angepassten .screenrc.
EEAA
92

Es gibt einige Möglichkeiten, dies zu tun, aber die nützlichste ist die Verwendung von GNU Screen .

Nachdem Sie sich angemeldet haben, laufen Sie screen. Dadurch wird eine andere Shell gestartet, die auf dem Bildschirm ausgeführt wird. Führen Sie Ihren Befehl aus und führen Sie dann ein Ctrl- aus a d.

Dadurch werden Sie von der Bildschirmsitzung "getrennt". An diesem Punkt können Sie sich abmelden oder etwas anderes tun, was Sie möchten.

Wenn Sie erneut eine Verbindung zur Bildschirmsitzung herstellen möchten, führen Sie dies einfach screen -RDüber die Shell-Eingabeaufforderung aus (als derselbe Benutzer, der die Sitzung erstellt hat).

EEAA
quelle
6
Screen hat eine ganze Reihe von Befehlen, die alle mit Strg-a beginnen. Wenn Sie nur eine zusätzliche lernen, beginnen Sie mit "Strg-a?". Dann wirst du nicht lernen, "Strg-a c" und "Strg-a n"
olafure
@olafure +1, danke. Es sieht so aus, als würde der Bildschirm zu meiner primären Toolbox gehören.
doc_id
tmux > screen. Probieren Sie es aus, Sie werden nie zurückkehren.
h0tw1r3
+1 für tmux. Ich habe den Bildschirm vor 5 Wochen aufgegeben.
Bryan Hunt
73

In bashist das disownSchlüsselwort perfekt dafür geeignet. Führen Sie Ihren Prozess zunächst im Hintergrund aus (verwenden Sie &oder geben Sie ^Zdann Folgendes ein bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

Indem jobsSie Folgendes eingeben , können Sie feststellen, dass der Prozess immer noch im Besitz der Shell ist:

$ jobs
[1]+  Running  wget

Wenn Sie sich zu diesem Zeitpunkt abmelden, wird die Hintergrundaufgabe ebenfalls beendet. Wenn Sie einen disownJob ausführen , löst bash den Job und lässt ihn weiterlaufen:

$ disown

Sie können dies bestätigen:

$ jobs
$ logout

Sie können sogar das &und disownin derselben Zeile kombinieren , z.

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

Dies ist nohupmeiner Meinung nach besser als das Ausführen , da dadurch keine nohup.outDateien im gesamten Dateisystem verstreut bleiben. Außerdem nohupmuss ausgeführt werden , bevor Sie den Befehl ausführen - disownverwendet werden können , wenn Sie später entscheiden , dass Sie in den Hintergrund wollen und die Aufgabe zu lösen.

Jeremy Visser
quelle
1
Das ist eine sehr gute Antwort, 1+. Die einzige Präferenz für nohup oder Screen wäre die Unabhängigkeit von bash und könnte mit einer anderen Shell verwendet werden. Aber ich werde mich an Ihre Vorgehensweise halten, wenn ich Bash verwende.
doc_id
Ja - dies ist bash-spezifisch, da bash die einzige Shell ist, die ich jemals verwendet habe. Ich frage mich, ob andere Shells etwas Ähnliches unterstützen (dh im Hintergrund ohne nohup starten) - es wäre fantastisch, wenn jemand andere Antworten für andere Shells posten könnte.
Jeremy Visser
1
siehe meine Antwort zeigt, wie es mit jedem Sh-Lookalike zu tun
w00t
1
+1, weil man sich später entscheiden kann. Genau in diesem Moment hatte ich ein Bedürfnis danach. arbeitete wie beworben
code_monk
37

Das Tool nohup, das auf den meisten Linux-Boxen verfügbar ist, erledigt dies.

Korjavin Ivan
quelle
1
Dies ist mit Abstand die einfachste Antwort. Jede Ausgabe von wird automatisch an nohup.out weitergeleitet und kann später überprüft werden.
Julian
3
nohup benötigt überhaupt kein zsh.
Aaron Brown
nohup ist die richtige Antwort, es ist kurz für kein Auflegen.
Kinjal Dixit
2
nohup ist auf weit mehr Maschinen als screen zu finden, daher sollten Sie wissen, wie man es benutzt.
Zenon
27

Um genau zu sein, werde ich auf tmux hinweisen , das die gleiche Grundidee wie screen hat:

tmux soll eine moderne, BSD-lizenzierte Alternative zu Programmen wie GNU Screen sein. Hauptmerkmale sind:

  • Eine leistungsstarke, konsistente, gut dokumentierte und leicht zu skriptende Befehlsoberfläche.
  • Ein Fenster kann horizontal und vertikal in Fensterbereiche aufgeteilt werden.
  • Die Fenster können frei verschoben und in der Größe geändert oder in vordefinierten Layouts angeordnet werden.
  • Unterstützung für Terminals mit UTF-8 und 256 Farben.
  • Kopieren und Einfügen mit mehreren Puffern.
  • Interaktive Menüs zur Auswahl von Fenstern, Sitzungen oder Clients.
  • Ändern Sie das aktuelle Fenster, indem Sie im Ziel nach Text suchen.
  • Terminalverriegelung manuell oder nach einer Zeitüberschreitung.
  • Eine saubere, einfach zu erweiterende, BSD-lizenzierte Codebasis, die sich derzeit in der aktiven Entwicklung befindet.

Es ist jedoch unendlich viel einfacher, auf Google zu suchen.

Heimwerker5
quelle
2
Verwenden "gnu screen"als Ihre Suchanfrage funktioniert ganz gut.
Gnur
4
+1000 für tmux!
mbq
11

Der Bildschirm ist zu groß, um Prozesse beim Abmelden am Laufen zu halten.

Versuchen Sie dtach :

dtach ist ein in C geschriebenes Programm, das die Funktion zum Entfernen des Bildschirms emuliert, mit der ein Programm in einer Umgebung ausgeführt werden kann, die vor dem steuernden Terminal geschützt ist. Zum Beispiel würde das Programm unter der Kontrolle von dtach nicht dadurch beeinträchtigt, dass das Terminal aus irgendeinem Grund getrennt wird.

dtach wurde geschrieben, weil screen meine Anforderungen nicht ausreichend erfüllte. Ich benötigte keine zusätzlichen Funktionen des Bildschirms, wie die Unterstützung mehrerer Terminals oder die Unterstützung der Terminalemulation. Bildschirm war auch zu groß, sperrig und hatte Quellcode, der schwer zu verstehen war.

Bildschirm störte auch meine Verwendung von Vollbild-Anwendungen wie Emacs und ircII aufgrund seiner übermäßigen Interpretation des Streams zwischen dem Programm und den angeschlossenen Terminals. dtach verfügt nicht über eine Terminalemulationsschicht und leitet den unformatierten Ausgabestream des Programms an die angeschlossenen Terminals weiter. Die einzige Eingabeverarbeitung, die dtach ausführt, besteht darin, nach dem Trennzeichen zu suchen (das signalisiert, dass dtach vom Programm getrennt werden soll) und den Suspend-Schlüssel zu verarbeiten (der dtach anweist, sich vorübergehend auszusetzen, ohne das laufende Programm zu beeinträchtigen). Beide können beides deaktiviert werden, wenn gewünscht.

Im Gegensatz zum Bildschirm hat dtach nur minimale Funktionen und ist extrem klein. Auf diese Weise kann dtach leichter auf Fehler und Sicherheitslücken überprüft werden und ist in Umgebungen mit begrenztem Speicherplatz, z. B. auf Rettungsdisketten, zugänglich.

sml
quelle
Danke. Ich bin hierher gekommen, um auch über dtach zu posten. Es ist jetzt meine Anlaufstelle für die Ablösung des Terminals. Bildschirm macht viel zu viel und stört die Eingabe in einem lächerlichen Ausmaß. Die Tatsache, dass der Bildschirm ein eigenes Termcap benötigt, ist ziemlich beunruhigend.
flauschiger
9

Hier ist eine Möglichkeit, einen Shell-Prozess zu dämonisieren, ohne dass externe Programme erforderlich sind:

( while sleep 5; do date; done ) <&- >output.txt &

Wenn Sie dann Ihre Sitzung schließen, wird der Job wie in der Datei output.txt beschrieben weiter ausgeführt (die Pufferung hat, sodass es eine Weile dauert, bis ein Wert ungleich Null angezeigt wird). Vergiss nicht, deinen Job nach dem Testen zu töten.

Alles, was Sie tun müssen, ist, den Job zu schließen und im Hintergrund zu arbeiten. Um wirklich gut zu sein, cd /haltet man sich also nicht an einem Reittier fest.

Dies funktioniert auch in einfachen sh unter Solaris.

w00t
quelle
Interessant. Daraus ergaben sich einige bemerkenswerte Fragen. Ich kann sehen, dass Sie die STDIN auf nichts setzen, der -Operator? Was ist der Unterschied zwischen < /dev/nullund &-? Ich vermute, dass STDIN (und andere STDOUT und STDERR) im Fall von STDIN entweder eine Datei von < fileoder ein Stream von <& streamzugewiesen werden könnte. Wäre es < /dev/nullin Ihrem obigen Beispiel dasselbe ? Und bezeichnet der Operator -oben eine Null als Stream?
doc_id
Wenn Sie x <& - ausführen, wird der Dateideskriptor x geschlossen. In diesem Fall gibt es kein x, wodurch bash standardmäßig auf 1 gesetzt wird, dh Standardeingabe. Wenn Sie </ dev / null verwenden und stdin nicht schließen, geben Sie dem Programm lediglich eine leere Datei als Eingabe.
19.
1
Und um ehrlich zu sein, ich weiß nicht wirklich, warum das die Sache dämonisiert, die Sie ausführen :-) Es funktioniert jedoch, wir verwenden es in der Produktion. Ich habe es entdeckt, als ich herumgespielt habe und gehofft habe, ich könnte einen Prozess in der Shell dämonisieren, ohne etwas Besonderes zu benötigen - also habe ich stdin geschlossen und das war genug. Ich sollte einige Shell-Quellen lesen, aber ich gehe davon aus, dass, wenn Sie stdin schließen und den Prozess im Hintergrund ausführen, dies auch den Prozess abbricht.
19.
2
Ich denke, der Grund dafür ist, dass ein SIGHUP (das eigentliche Signal, das bewirkt, dass das Kind beendet wird, wenn die Shell stirbt) ausgelöst wird, wenn ein übergeordneter Prozess das stdin-Handle seines Kindes schließt. Wenn stdin jedoch mit null beginnt und nicht nachträglich geschlossen wird, kann das übergeordnete Element das SIGHUP nicht auslösen. Netter Fund, daran hätte ich nie gedacht.
Jeremy Visser
@ JeremyVisser das klingt wirklich plausibel!
17.
7

Der atBefehl kann in solchen Situationen hilfreich sein. Geben Sie zum Beispiel Folgendes ein:

at now

Anschließend können Sie einen Befehl oder eine Reihe von Befehlen eingeben, die ausgeführt werden. Die Ergebnisse sollten per E-Mail an Sie gesendet werden, wenn die E-Mail-Einstellungen auf dem Computer korrekt sind.

Stattdessen nowkönnen Sie eine Uhrzeit optional mit einem Datum oder einem Zeitausdruck wie angeben now + 15 minutes. Sehen Sie man atfür weitere Details.

rjmunro
quelle
7

byobuUnter Ubuntu gibt es ein nettes Frontend zum Bildschirm. Durch Drücken von Ctrl- erhalten ?Sie eine Liste aller Tastaturkürzel. Es fügt eine Statusleiste hinzu, die nützlich sein kann, um die CPU-Auslastung, den Festplattenspeicher usw. zu überwachen. Insgesamt bietet es eine Erfahrung, die ich als terminalbasierte VNC-Verbindung bezeichnen würde.

nohup Ermöglicht das Starten eines Jobs im Hintergrund, wobei die Ausgabe an eine Protokolldatei weitergeleitet wird, die bei Bedarf immer nach / dev / null umgeleitet werden kann.

John Beckett
quelle