Wie kann ich einen bereits laufenden Prozess unter nohup?
Frage
Ich habe einen Prozess, der bereits für eine lange Zeit ausgeführt wird und nicht will, es zu beenden.
Wie kann ich es unter nohup (das heißt, wie kann ich es verursachen, auch weiterlaufen, wenn ich das Terminal schließen?)
Lösung
Mit dem Job Control von bash den Prozess in die schicken Hintergrund:
- Strg + Z zu stoppen (Pause), um das Programm und zurück in die Schale bekommen.
-
bg
es im Hintergrund laufen zu lassen. -
disown -h [job-spec]
wo [Job-Spec] die Auftragsnummer ist (wie%1
für den ersten Lauf Job, findet über Ihre Nummer mit demjobs
Befehl), so dass der Auftrag nicht getötet wird, wenn das Terminal geschlossen .
Andere Tipps
aus irgendeinem Grunde Angenommen Strg + Z ist auch nicht funktioniert, zu einem anderen Terminal geht, finden die Prozess-ID (mit ps
) und ausführen:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
wird den Prozess auszusetzen und SIGCONT
wird den Prozess, im Hintergrund fortgesetzt. So, jetzt, schließen sowohl Ihre Terminals nicht Ihren Prozess stoppen.
Der Befehl einen laufenden Auftrag aus der Schale zu trennen (= macht es nohup) ist disown
und ein grundlegender Shell-Befehl.
Von bash-Manpage (man bash):
disown [-ar] [-h] [jobspec ...]
Ohne Optionen wird jede jobspec aus der Tabelle der aktiven Jobs entfernt. Wenn die Option -h angegeben ist, ist jede jobspec nicht aus der Tabelle entfernt, aber markiert ist, so dass SIGHUP nicht auf den Auftrag gesendet wird, wenn die Schale ein SIGHUP empfängt. Wenn kein jobspec ist Gegenwart und weder die -a noch die Option -r zugeführt wird, wird der aktuelle Auftrag verwendet. Wenn kein jobspec zugeführt wird, die Option -a bedeutet, zu entfernen oder alle Aufträge markieren; die Option -r ohne jobspec Argument schränkt Betrieb Jobs ausgeführt werden. Die Rückkehr Wert ist 0, es sei denn ein jobspec keine gültige Job nicht angeben.
Das bedeutet, dass ein einfaches
disown -a
werden alle Aufträge aus der Job-Tabelle entfernen und macht sie nohup
Das sind gute Antworten oben, ich wollte nur eine Klarstellung hinzuzufügen:
Sie können keine pid oder Prozess disown
, disown
Sie einen Job, und das ist ein wichtiger Unterschied.
Ein Job ist etwas, das eine Vorstellung eines Prozesses ist, der an einer Schale angebracht ist, daher müssen Sie den Job in den Hintergrund werfen (es ist nicht aussetzen) und dann verleugnet es.
Ausgabe:
% jobs
[1] running java
[2] suspended vi
% disown %1
Siehe http://www.quantprinciple.com/ investieren / index.php / docs / tipsandtricks / Unix / Jobcontrol / für eine detailliertere Erörterung von Unix Job Control.
Leider disown
ist spezifisch für bash und nicht in allen Schalen zur Verfügung.
Bestimmte Unix-Varianten (z AIX und Solaris) eine Option auf dem nohup
Befehl selbst die zu einem laufenden Prozess angewandt werden kann:
nohup -p pid
Node Antwort ist wirklich groß, aber es ließ die Frage offen, wie stdout und stderr umgeleitet bekommen. Ich fand eine Lösung auf Unix & Linux , aber es ist auch nicht vollständig. Ich möchte diese beiden Lösungen verschmelzen. Hier ist sie:
Für meinen Test habe ich einen kleinen Bash-Skript namens loop.sh, die die pid von selbst druckt mit einer Minute Schlaf in einer Endlosschleife.
$./loop.sh
Sie nun die PID dieses Prozesses erhalten irgendwie. Normalerweise ps -C loop.sh
ist gut genug, aber es ist in meinem Fall gedruckt.
Jetzt können wir zu einem anderen Endgerät wechseln (oder drücken Sie ^ Z und in der gleichen Klemme). Nun sollte gdb
dieses Verfahren angebracht werden.
$ gdb -p <PID>
Dies stoppt das Skript (falls ausgeführt). Sein Zustand kann durch ps -f <PID>
überprüft werden, wo das Feld STAT
'T +' (oder im Fall von Z ^ 'T') ist, 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
Schließen (1) gibt Null auf Erfolg.
(gdb) call open("loop.out", 01102, 0600)
$6 = 1
Öffnen (1) gibt den neuen Dateideskriptor wenn sie erfolgreich sind.
Dieses offen ist gleich mit open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
.
Statt O_RDWR
O_WRONLY
angewendet werden könnte, aber /usr/sbin/lsof
sagt 'u' für alle std * Datei-Handler (FD
Spalte), die O_RDWR
ist.
Ich habe die Werte in /usr/include/bits/fcntl.h Header-Datei.
Die Ausgabedatei mit O_APPEND
geöffnet werden kann, wie nohup
tun würde, aber dies wird nicht von man open(2)
, wegen möglicher NFS Probleme vorgeschlagen.
Wenn wir -1 als Rückgabewert zu erhalten, dann call perror("")
gibt die Fehlermeldung. Wenn wir die errno benötigen, p errno
gdb comand verwenden.
Jetzt können wir die neu umgeleitet Datei überprüfen. /usr/sbin/lsof -p <PID>
druckt:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
Wenn wir wollen, können wir stderr auf eine andere Datei umleiten, wenn wir mit call close(2)
und call open(...)
wollen wieder einen anderen Dateinamen verwendet wird.
Nun ist der beigefügte bash
freigegeben werden, und wir können gdb
beenden:
(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q
Wenn das Skript von gdb
von einem anderen Terminal gestoppt wurde weiterhin um es auszuführen. Wir können loop.sh Terminal wechseln. Nun ist es nicht alles auf den Bildschirm schreiben, aber läuft und das Schreiben in die Datei. Wir haben es in den Hintergrund zu stellen. So drücken ^Z
.
^Z
[1]+ Stopped ./loop.sh
(Jetzt sind wir in dem gleichen Zustand wie wenn ^Z
am Anfang gedrückt wurde.)
Jetzt können wir den Status des Auftrags prü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
So Prozess im Hintergrund ausgeführt werden soll und vom Terminal abgelöst. Die Zahl in der Ausgabe des jobs
Befehls in eckigen Klammern identifiziert den Job innerhalb bash
. Wir können in der in bash
Befehle gebaut folgenden verwenden, um ein ‚%‘ Zeichen vor der Auftragsnummer der Anwendung:
$ 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 von der rufenden bash beenden. Der Prozess läuft im Hintergrund weiter läuft. Wenn wir seine PPID verlassen wird 1 (init (1) -Prozess) und der Steueranschluss wurde nicht bekannt.
$ 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
GDB Material kann automatisiert werden Erstellen einer Datei (z.B. loop.gdb) enthält die Befehle und Lauf gdb -q -x loop.gdb -p <PID>
. Mein loop.gdb sieht wie folgt aus:
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
Oder man kann die folgenden Einzeiler verwendet stattdessen:
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
Ich hoffe, dass dies eine ziemlich vollständige Beschreibung der Lösung ist.
So senden Prozess laufen nohup ( http://en.wikipedia.org/wiki/Nohup)
nohup -p pid
, es nicht für mich gearbeitet
Dann habe ich versucht die folgenden Befehle ein und es funktionierte sehr fein
-
einige einKommando Run, sagen
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
. -
Strg + Z zu stoppen (Pause), um das Programm und sich wieder auf die Schale.
-
bg
es im Hintergrund laufen zu lassen. -
disown -h
so dass der Prozess nicht getötet wird, wenn die Klemme geschlossen wird. -
exit
Typ aus der Schale zu bekommen, weil jetzt Sie gut sind wie die Operation zu gehen, wird im Hintergrund in einem eigenen Prozess ausgeführt werden, so dass es nicht zu einer Schale gebunden.
Dieses Verfahren ist das Äquivalent nohup SOMECOMMAND
von ausgeführt wird.
Auf meinem AIX-System habe ich versucht,
nohup -p processid>
Das hat gut funktioniert. Sie fuhr fort, meinen Prozess auch nach dem Schließen Terminal-Fenster laufen zu lassen. Wir haben als Standard-Shell ksh so die bg
und disown
Befehle funktionieren nicht.
- ctrl + z - (! Nicht abbrechen geht), wird dies den Job Pause
-
bg
- dies wird die Arbeit im Hintergrund setzen und die Rück Prozesses in Laufen -
disown -a
- dies wird schneiden alle die Anlage mit Job (so können Sie das Terminal schließen und es wird immer noch ausgeführt wird)
Diese einfachen Schritte können Sie das Terminal schließen, während Prozess am Laufen zu halten.
Es wird nicht auf nohup
setzen (basierend auf meinem Verständnis Ihrer Frage, Du es hier nicht brauchen).
Das funktioniert für mich auf Ubuntu Linux, während in tcshell.
-
Strg Z es auf Pause
-
bg
im Hintergrund laufen zu lassen -
jobs
seine Auftragsnummer zu erhalten -
nohup %n
wobei n die Auftragsnummer