Wie kann ich einen laufenden Prozess deaktivieren und ihn einer neuen Bildschirmshell zuordnen?

159

Ich habe ein laufendes Programm auf einer SSH-Shell. Ich möchte es anhalten und seine Ausführung wieder aufnehmen können, wenn ich zurückkomme.

Eine Möglichkeit, dies zu tun, bestand darin, sein Eigentum auf eine Bildschirmhülle zu übertragen und sie so dort laufen zu lassen.

Gibt es eine andere Vorgehensweise?

levesque
quelle
8
Siehe auch Kann ich einen bereits gestarteten Prozess nicht starten / überprüfen? und Resume-Befehl, der in einer gelöschten SSH-Sitzung ausgeführt wird und in dem mehrere (derzeit) hier nicht erwähnte ptrace-basierte Lösungen erwähnt werden.
Gilles
Bei Fragen wie unix.stackexchange.com/a/4039/13496 höre ich von Retty und Neercs . Hmmm ... Wunder , wenn es smth wie ein „ist Bildschirm hier“ Schicht , bevor ich einen Prozess beim nächsten Mal soll laufen verliere ich den Top - Terminal in der Zukunft, dass es leicht zu reißen zurück in der stdin / out / err machen
Marcos
Das sekundäre / implizite Problem in dieser Frage, das ich nicht ergründen kann, ist ... warum hat die Shell einen angehaltenen Job abgelehnt, wenn es einen neueren / gerade gestarteten Job im Hintergrund gibt , der nicht einmal stdin benötigt / wartet? Dies ist die Behandlung, an die ich mich gewöhnt habe, also weiß ich nicht, was hier anders gelaufen ist ...
Marcos

Antworten:

86

Verwenden Sie GNU screenam besten.

Startbildschirm läuft beim ersten Login - ich laufen screen -D -R, laufen Ihren Befehl, und entweder trennen oder zu unterbrechen sie mit CTRL-Zund trennen Sie von Bildschirm durch Drücken CTRL-Adann D.

Wenn Sie sich erneut am Computer anmelden, stellen Sie die Verbindung durch Ausführen wieder her screen -D -R. Sie befinden sich in derselben Shell wie zuvor. jobsWenn Sie dies getan haben, können Sie den angehaltenen Prozess ausführen , um %1ihn wieder in den Vordergrund zu stellen.

Andrew Yochum
quelle
2
Wow, ich kann nicht glauben, dass eine Antwort von GNU Screen derzeit die niedrigste Bewertung hat. Vermisse ich etwas?
Faheem Mitha
1
Vielleicht! Scheint mir das Beste zu sein.
Andrew Yochum
1
Rückblickend scheint dies die schmerzloseste Lösung zu sein, vorausgesetzt, Sie können entsprechend planen und Ihre Prozesse in einer Bildschirmumgebung starten. Wie auch immer, ich habe es zur offiziellen Antwort gemacht!
Levesque
28
Ich denke, das beantwortet die Frage nicht. Die Frage beginnt mit " Ich habe ein Programm ausgeführt ". Diese Antwort geht davon aus, dass es noch nicht läuft ...
Anko
ja er hat klar geschrieben er möchte es in eine screen session bekommen :-)
Florian Heigl
112

Sie können "Besitz" des Programms von der Shell mit dem disowneingebauten widerrufen :

# press Ctrl+Z to suspend the program
bg
disown

Dies weist die Shell jedoch nur an, beim Beenden der Shell kein SIGHUPSignal an das Programm zu senden . Das Programm behält alle Verbindungen zum Terminal bei, normalerweise als Standardeingabe-, Ausgabe- und Fehlerdatenströme. Es gibt keine Möglichkeit, diese an ein anderes Terminal anzuschließen. (Der Bildschirm emuliert ein Terminal für jedes Fenster, sodass die Programme an das Bildschirmfenster angehängt werden.)


Es ist möglich , die filedescriptors in eine andere Datei wieder zu befestigen , indem das Programm in einem Debugger Befestigung (dh unter Verwendung ptrace) und nennen es machen open, dupund close. Es gibt einige Tools, die dies tun. Dies ist ein kniffliger Prozess, und manchmal stürzt der Prozess stattdessen ab. Folgende Möglichkeiten stehen zur Verfügung: (Links, die aus Antworten auf " Wie kann ich einen laufenden Prozess verbergen und einer neuen Bildschirmshell zuordnen?" Und " Kann ich einen bereits gestarteten Prozess nicht starten / überprüfen" ):

Gilles
quelle
disownEntfernt den Prozess aus der Jobsteuerungsliste.
Strg-Alt-Delor
3
Warum nicht disown -h?
Cees Timmerman
@CeesTimmerman Damit bleibt der Job in der Jobtabelle der Shell, aber was ist der Vorteil davon?
Gilles
@Gilles: also du kannst noch fgoder killes, und sehen, ob es von selbst endet.
Peter Cordes
Welche erwähnten Dienstprogramme arbeiten mit einer Gruppe von Prozessen (z. B. bzcat a.bz2 | grep text) zusammen? Mann für reptyrsagt, dass es nicht unterstützt, die Prozesse mit Kindern zu verschieben.
dma_k
64

Um einen Prozess zwischen Terminals zu verschieben oder einen nicht besessenen erneut anzuschließen , können Sie z . B. Reptyr verwenden .

Jofel
quelle
1
Ja, das hat es gerettet, danke! Ich habe auf der Website des Autors nachgelesen, wie es besser funktioniert als vergleichbare oder ältere Tools, z. für ncurses programme.
Marcos
4
Das ist fantastisch; es sollte die missliche lage einer freundin lösen, ihre arbeit ständig zu verlieren, indem man sie direkt in ssh laufen lässt und dann in einen zug steigen muss. "Hoppla, ich habe vergessen, den Bildschirm zu benutzen. Schon wieder."
Adam Katz
3
+1 Obwohl die akzeptierte screenAntwort natürlich ideal ist, beantwortet sie nicht die Frage, die speziell nach einer Möglichkeit zum Verschieben eines aktuell ausgeführten Prozesses screenoder dergleichen verlangt . Siehe auch diese Antwort: serverfault.com/a/284795
toxefa
1
Absoluter Lebensretter. Ich konnte erneut eine Verbindung zum Ausführen von apt dist-upgrade herstellen, das darauf wartete, von einem Benutzer bestätigt zu werden.
Andig
28

Meine bevorzugte Lösung ist die Verwendung von tmux. Sie können die Sitzung trennen und in einem anderen Terminal erneut anfügen.

Wenn Sie sich von der vorherigen Sitzung getrennt haben, können Sie das Terminal sicher schließen. später verwenden tmux attach, um zur Sitzung zurückzukehren, auch wenn Sie sich abgemeldet haben.

Gänseblümchen
quelle
1
Sie können auch Ihre Sitzung mit Ihrem Freund teilen und mehrere Fenster und Scheiben und vieles mehr verwenden! liebe es ^ _ ^
igor
Beispiel für die Verwendung bitte?
Vitaly Zdanevich
21

Es gibt auch ein kleines Hilfsprogramm namens retty , mit dem Sie laufende Programme an ein anderes Terminal anschließen können.

Adamg
quelle
19

Ich benutze es nicht regelmäßig, aber neercs behauptet, dies zu unterstützen. Es ist ein screenähnliches Programm mit verschiedenen ausgefallenen Funktionen wie einer besseren Fensterverwaltung, aber das Wichtigste, das es bietet, ist die Möglichkeit, einen Prozess in ein Fenster zu importieren

Michael Mrozek
quelle
2
Interessant. Es spielt zwar dirty ( ptrace), manipuliert aber nicht nur die Dateideskriptoren, sondern gibt den Prozess vor. Es ist in der Lage zu greifen find /, stürzte aber eine interaktive Bash.
Gilles
@ Gilles Ich kann mich nicht erinnern, wie es gelaufen ist, als ich es versucht habe, aber es hat keinen guten Ruf. Mir wurde gesagt, dass es ziemlich regelmäßig scheitert
Michael Mrozek
9

Wenn Sie es nur anhalten und anschließend neu starten möchten, können Sie killmit STOPoder CONTsignalisieren.

Finden Sie zuerst die Prozesse PID mit

$ ps aux

Senden Sie dann die Signale an die PID, die für den Prozess aufgelistet ist

$ kill -STOP <PID>

$ kill -CONT <PID>
Yunzen
quelle
9

"injcode" von ThomasHabets scheint genau das zu sein, was ich brauche:

https://github.com/ThomasHabets/injcode

Mit dem Programm injcode kann beliebiger Code in einen laufenden Prozess eingefügt werden, unabhängig davon, ob Sie es zuvor gewusst haben und screen oder tmux ausgeführt haben

Aus der README:

Beispiel 1: Verschieben von IRSI von einem Terminal zu einem anderen

Verschiebe es vielleicht auf einen Bildschirm.

Starten Sie zuerst irssi in einem Terminal.

Führen Sie den injcode in einem anderen Terminal aus: $ injcode -m retty

Irssi sollte nun auf das zweite Terminal verschoben werden, einschließlich eines neuen steuernden Terminals.

user2688272
quelle
1

Das hat bei mir funktioniert:

  1. bg der Prozess
  2. jobs -l Prozessnummer finden
  3. tmux Starten Sie den Shell Window Manager
  4. reptyr -L PROCESSNUMBER

reptyr's -Lwar notwendig, um dies zum Laufen zu bringen:

-L Like '-l', but also redirect the child's stdio to the slave.

wegen dieses Fehlers:

$ reptyr 30622

[-] Unable to open the tty in the child.
Unable to attach to pid 30622: Permission denied

Und mit -L

$ reptyr -L 30622
Opened a new pty: /dev/pts/4
Guaka
quelle