Frage Wie stelle ich einen bereits laufenden Prozess unter nohup?


Ich habe einen Prozess, der schon lange läuft und nicht enden will.

Wie stelle ich es unter nohup (das heißt, wie führe ich es weiter, selbst wenn ich das Terminal schließe?)


775
2018-03-09 08:33


Ursprung


Antworten:


Verwendung der Jobkontrolle of bash, um den Prozess in den Hintergrund zu stellen:

  1. Strg+Z um das Programm anzuhalten (pausieren) und zur Shell zurückzukehren.
  2. bg um es im Hintergrund laufen zu lassen.
  3. disown -h [job-spec] wo [Auftragsspezifikation] ist die Auftragsnummer (wie %1 für den ersten laufenden Job; Finde über deine Nummer mit dem jobs Befehl), damit der Job beim Schließen des Terminals nicht beendet wird.

1153
2018-03-09 08:41



Angenommen, aus irgendeinem Grund Strg+Z funktioniert auch nicht, gehen Sie zu einem anderen Terminal, finden Sie die Prozess - ID (mit ps) und Renn:

kill -20 PID 
kill -18 PID

kill -20 (SIGTSTP) wird den Prozess aussetzen und kill -18 (SIGCONT) wird den Prozess im Hintergrund fortsetzen. Wenn Sie also beide Terminals schließen, wird Ihr Prozess nicht gestoppt.


141
2018-04-23 08:01



Der Befehl zum Trennen eines laufenden Jobs von der Shell (= macht es nohup) ist disown und ein einfacher Shell-Befehl.

Von Bash-Manpage (Mann bash):

verleugnen [-ar] [-h] [jobspec ...]

Ohne Optionen wird jede Jobspec aus der Tabelle der aktiven Jobs entfernt. Wenn die Option -h angegeben wird, gilt dies nicht für jede Jobspec   aus der Tabelle entfernt, aber markiert, so dass SIGHUP nicht an den Job gesendet wird, wenn die Shell eine SIGHUP erhält. Wenn keine Jobspec ist   vorhanden ist und weder die Option -a noch die Option -r angegeben ist, wird der aktuelle Job verwendet. Wenn keine Jobspec angegeben wird, die Option -a   bedeutet, alle Jobs zu entfernen oder zu markieren; Die Option -r ohne ein Jobspec-Argument beschränkt die Operation auf laufende Jobs. Die Rückkehr   Der Wert ist 0, es sei denn, eine Jobspezifikation gibt keinen gültigen Job an.

Das bedeutet, dass ein einfaches

disown -a

Entfernt alle Jobs aus der Job-Tabelle und macht sie nohup


72
2018-03-09 08:38



Dies sind gute Antworten oben, ich wollte nur eine Klarstellung hinzufügen:

Du kannst nicht disown ein Pid oder Prozess, du disown ein Job, und das ist eine wichtige Unterscheidung.

Ein Job ist eine Vorstellung von einem Prozess, der an eine Shell angehängt ist. Daher müssen Sie den Job in den Hintergrund werfen (nicht anhalten) und ihn dann ablehnen.

Problem:

%  jobs
[1]  running java 
[2]  suspended vi
%  disown %1

Sehen http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ für eine detailliertere Diskussion von Unix Job Control.


60
2017-11-19 15:48



Leider nicht disown ist spezifisch für Bash und nicht in allen Shells verfügbar.

Bestimmte Varianten von Unix (z. B. AIX und Solaris) haben eine Option auf dem nohup Befehl selbst, der auf einen laufenden Prozess angewendet werden kann:

nohup -p pid

Sehen http://en.wikipedia.org/wiki/Nohup


36
2018-03-16 23:49



Die Antwort von Node ist wirklich großartig, aber es hat die Frage offen gelassen, wie man stdout und stderr umleiten kann. Ich habe eine Lösung gefunden Unix und Linux, aber es ist auch nicht vollständig. Ich möchte diese beiden Lösungen zusammenführen. Hier ist es:

Für meinen Test habe ich ein kleines Bash-Skript namens loop.sh erstellt, das die PID von sich selbst mit einem winzigen Schlaf in einer Endlosschleife druckt.

$./loop.sh

Bekommen Sie jetzt die PID dieses Prozesses irgendwie. Gewöhnlich ps -C loop.sh ist gut genug, aber es ist in meinem Fall gedruckt.

Jetzt können wir zu einem anderen Terminal wechseln (oder drücken Sie ^ Z und im selben Terminal). Jetzt gdb sollte diesem Prozess beigefügt werden.

$ gdb -p <PID>

Dies stoppt das Skript (wenn es ausgeführt wird). Sein Zustand kann durch überprüft werden ps -f <PID>, bei dem die STAT Feld ist 'T +' (oder im Fall von 'Z' T '), was bedeutet (man ps (1))

    T Stopped, either by a job control signal or because it is being traced
    + is in the foreground process group

(gdb) call close(1)
$1 = 0

Close (1) gibt bei Erfolg Null zurück.

(gdb) call open("loop.out", 01102, 0600)
$6 = 1

Open (1) gibt bei Erfolg den neuen Dateideskriptor zurück.

Dieses Öffnen ist gleich mit open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). Anstatt von O_RDWR  O_WRONLY könnte angewendet werden, aber /usr/sbin/lsof sagt 'u' für alle std * Dateihandler (FD Spalte), was ist O_RDWR.

Ich habe die Werte in der Headerdatei /usr/include/bits/fcntl.h überprüft.

Die Ausgabedatei könnte mit geöffnet werden O_APPEND, wie nohup würde tun, aber das wird nicht von vorgeschlagen man open(2)wegen möglicher NFS-Probleme.

Wenn wir -1 als Rückgabewert erhalten, dann call perror("") druckt die Fehlermeldung. Wenn wir das errno brauchen, verwenden Sie p errno gdb-Befehl.

Jetzt können wir die neu umgeleitete Datei überprüfen. /usr/sbin/lsof -p <PID> Drucke:

loop.sh <PID> truey    1u   REG   0,26        0 15008411 /home/truey/loop.out

Wenn wir wollen, können wir stderr in eine andere Datei umleiten, wenn wir es benutzen wollen call close(2) und call open(...) wieder mit einem anderen Dateinamen.

Jetzt das beigefügt bash muss freigegeben werden und wir können aufhören gdb:

(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q

Wenn das Skript gestoppt wurde gdb von einem anderen Terminal läuft es weiter. Wir können zurück zum Terminal von loop.sh wechseln. Jetzt schreibt es nichts mehr auf den Bildschirm, sondern läuft und schreibt in die Datei. Wir müssen es in den Hintergrund stellen. Also drücken Sie ^Z.

^Z
[1]+  Stopped                 ./loop.sh

(Jetzt sind wir im selben Zustand wie wenn ^Z wurde am Anfang gedrückt.)

Jetzt können wir den Status des Jobs überprüfen:

$ ps -f 24522
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
$ jobs
[1]+  Stopped                 ./loop.sh

Der Prozess sollte also im Hintergrund laufen und vom Terminal getrennt sein. Die Nummer in der jobs Die Ausgabe des Befehls in eckigen Klammern kennzeichnet den Job darin bash. Wir können in den folgenden eingebauten verwenden bash Befehle, die vor der Jobnummer ein '%' Zeichen setzen:

$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh

Und jetzt können wir die Calling Bash verlassen. Der Prozess wird weiterhin im Hintergrund ausgeführt. Wenn wir seine PPID beenden, wird 1 (init (1) -Prozess) und das Steuerterminal wird unbekannt.

$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)

KOMMENTAR

Das gdb-Zeug kann automatisiert werden, indem eine Datei (z. B. loop.gdb) erstellt wird, die die Befehle enthält und ausgeführt wird gdb -q -x loop.gdb -p <PID>. Meine loop.gdb sieht folgendermaßen aus:

call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit

Oder man kann stattdessen den folgenden Liner verwenden:

gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>

Ich hoffe, dies ist eine ziemlich vollständige Beschreibung der Lösung.


21
2017-10-10 09:35



So senden Sie laufenden Prozess an nohup (http://en.wikipedia.org/wiki/Nohup)

nohup -p pid Es hat nicht für mich funktioniert

Dann habe ich die folgenden Befehle ausprobiert und es hat sehr gut funktioniert

  1. Führe etwas SOMECOMMAND, sagen /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Strg+Z um das Programm anzuhalten (pausieren) und zur Shell zurückzukehren.

  3. bg um es im Hintergrund laufen zu lassen.

  4. disown -h damit der Prozess beim Schließen des Terminals nicht beendet wird.

  5. Art exit um aus der Shell herauszukommen, denn jetzt ist es gut zu gehen, da die Operation in ihrem eigenen Prozess im Hintergrund läuft, also nicht an eine Shell gebunden ist.

Dieser Prozess entspricht dem Ausführen nohup SOMECOMMAND.


6
2017-09-27 06:48