Jak umieścić już uruchomiony proces pod nohup?

Mam proces, który jest już uruchomiony przez długi czas i nie chcę go kończyć.

Jak umieścić go pod nohup (czyli jak spowodować, że będzie nadal działać, nawet jeśli zamknę terminal?)

 789
Author: Peter Mortensen, 2009-03-09

10 answers

Użycie kontroli zadania bash do wysłania procesu w tło:

  1. Ctrl+Z aby zatrzymać (wstrzymać) program i wrócić do powłoki.
  2. bg aby uruchomić go w tle.
  3. disown -h [job-spec] Gdzie [job-spec] jest numerem zadania (jak %1 dla pierwszego uruchomionego zadania; Znajdź numer za pomocą polecenia jobs), aby zadanie nie zostało zabite po zamknięciu terminala.
 1177
Author: Node,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 00:19:14

Załóżmy z jakiegoś powodu Ctrl+z również nie działa, przejdź do innego terminala, znajdź identyfikator procesu (używając ps) i uruchom:

kill -20 PID 
kill -18 PID

kill -20 (SIGTSTP) zawiesi proces i kill -18 (SIGCONT) wznowi proces, w tle. Więc teraz zamknięcie obu terminali nie zatrzyma procesu.

 146
Author: Pungs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-01 00:27:00

Polecenie oddzielające uruchomione zadanie od powłoki (=sprawia, że nohup) to disown i podstawowe polecenie powłoki.

From bash-manpage (Man bash):

Disown [- ar] [- h] [jobspec ...]

Bez opcji, każdy jobspec jest usuwany z tabeli aktywnych zadań. Jeśli podana jest opcja-h, każde jobspec nie jest usunięto z tabeli, ale jest oznaczony tak, że SIGHUP nie jest wysyłany do zadania, jeśli powłoka otrzyma SIGHUP. Jeśli nie jobspec jest teraźniejszość, a Ani - a Nie podano opcji-r, używane jest bieżące zadanie. Jeśli nie podano jobspec, opcja -a oznacza usunięcie lub zaznaczenie wszystkich zadań; opcja - R bez argumentu jobspec ogranicza operację do uruchomionych zadań. Powrót wartość wynosi 0, chyba że jobspec nie określa poprawnego zadania.

To znaczy, że prosty

disown -a

Usunie wszystkie zadania z tabeli zadań i uczyni je nohup

 76
Author: serioys sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-02 23:18:17

To są dobre odpowiedzi powyżej, chciałem tylko dodać wyjaśnienie:

Nie możesz disown PID lub procesu, ty disown pracę, i to jest ważne rozróżnienie.

Zadanie jest czymś, co jest pojęciem procesu, który jest dołączony do powłoki, dlatego musisz rzucić zadanie w tło (nie zawiesić go), a następnie się go wyrzec.

Wydanie:

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

Zobacz http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol / na bardziej szczegółowe omówienie kontroli zadań systemu Unix.

 62
Author: Q Boiler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 00:20:34

Unrfortunately disown jest specyficzny dla Basha i nie jest dostępny we wszystkich powłokach.

AIX i Solaris) mają opcję w Komendzie nohup, która może być zastosowana do uruchomionego procesu:
nohup -p pid

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

 36
Author: Dale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 00:21:03

Odpowiedź węzła jest naprawdę świetna, ale pozostawiło otwarte pytanie, jak można przekierować stdout i stderr. Znalazłem rozwiązanie na Unix & Linux, ale również nie jest kompletne. Chciałbym połączyć te dwa rozwiązania. Oto ona:

Do mojego testu zrobiłem mały skrypt Basha o nazwie loop.sh, który drukuje sam pid z minutowym snem w nieskończonej pętli.

$./loop.sh

Teraz zdobądź w jakiś sposób PID tego procesu. Zazwyczaj ps -C loop.sh jest wystarczająco dobry, ale jest wydrukowany w moim case.

Teraz możemy przełączyć się na inny terminal (lub nacisnąć ^z i w tym samym terminalu). Teraz gdb powinny być dołączone do tego procesu.

$ gdb -p <PID>

To zatrzymuje skrypt (jeśli jest uruchomiony). Jego stan można sprawdzić za pomocą ps -f <PID>, gdzie pole STAT to "T+" (lub w przypadku ^z "T"), co oznacza (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) zwraca zero po pomyślnym zakończeniu.

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

Open(1) zwraca nowy deskryptor pliku, jeśli się powiedzie.

Ten otwarty jest równy open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). Zamiast z O_RDWR O_WRONLY można zastosować, ale /usr/sbin/lsof mówi " u " dla wszystkich programów obsługi plików std* (kolumnaFD), czyli O_RDWR.

Sprawdziłem wartości w /usr / include/bits / fcntl.plik nagłówkowy H.

Plik wyjściowy może być otwarty za pomocą O_APPEND, tak jak zrobiłby to nohup, ale nie jest to sugerowane przez man open(2), ze względu na Możliwe problemy z NFS.

Jeśli otrzymamy -1 jako wartość zwracaną, to call perror("") wyświetla komunikat o błędzie. Jeśli potrzebujemy errno, użyj p errno GDB comand.

Teraz możemy sprawdzić nowo przekierowany plik. /usr/sbin/lsof -p <PID> druki:

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

Jeśli chcemy, możemy przekierować stderr do innego pliku, jeśli chcemy użyć call close(2) i call open(...) ponownie używając innej nazwy pliku.

Teraz dołączony bash musi zostać zwolniony i możemy zamknąć gdb:

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

Jeśli skrypt został zatrzymany przez gdb z innego terminala, nadal jest uruchamiany. Możemy przełączyć się z powrotem na loop.sh / align = "left" / Teraz nie zapisuje niczego na ekranie, ale uruchamia i zapisuje do pliku. My muszę to umieścić w tle. Więc naciśnij ^Z.

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

(teraz jesteśmy w tym samym stanie, jak gdyby ^Z został naciśnięty na początku.)

Teraz możemy sprawdzić stan pracy:

$ 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

Więc proces powinien być uruchomiony w tle i odłączony od terminala. Liczba w wyjściu polecenia jobs w nawiasach kwadratowych określa zadanie wewnątrz bash. Możemy użyć następujących wbudowanych poleceń bash, stosując znak " % " przed numerem zadania :

$ 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
A teraz możemy zrezygnować z wywołującego Basha. Proces kontynuowany jest w tle. Jeśli zamkniemy jego PPID become 1(proces init (1)) i terminal sterujący stanie się Nieznany.
$ 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)

Komentarz

Rzeczy gdb można zautomatyzować tworząc plik (np. loop.gdb) zawierający polecenia I run gdb -q -x loop.gdb -p <PID>. Moja pętla.gdb wygląda tak:

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

Lub można użyć jednego linera zamiast:

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

Mam nadzieję, że to dość kompletny opis rozwiązania.

 21
Author: TrueY,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 12:36:27

Aby wysłać uruchomiony proces do nohup ( http://en.wikipedia.org/wiki/Nohup )

nohup -p pid , to nie działa dla mnie

Potem próbowałem następujących poleceń i działało bardzo dobrze

  1. Run some SOMECOMMAND, powiedz /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl+Z aby zatrzymać (wstrzymać) program i wrócić do powłoki.

  3. bg aby uruchomić go w tle.

  4. disown -h aby proces nie został zabity, gdy terminal się zamyka.

  5. Wpisz exit, aby wydostać się z powłoki, ponieważ teraz możesz przejść, ponieważ operacja będzie działać w tle we własnym procesie, więc nie jest powiązana z powłoką.

Ten proces jest odpowiednikiem running nohup SOMECOMMAND.

 6
Author: minhas23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 00:17:47

W moim systemie AIX, próbowałem

nohup -p  processid>
To zadziałało dobrze. Nadal uruchamiał mój proces nawet po zamknięciu okien terminala. Mamy ksh jako domyślną powłokę, więc polecenia bg i disown nie działały.
 1
Author: guest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 00:18:26
  1. ctrl + z - spowoduje to wstrzymanie pracy(nie będzie anulować!)
  2. bg - spowoduje to umieszczenie zadania w tle i zwrócenie w uruchomionym procesie
  3. disown -a - spowoduje to przecięcie całego załącznika z jobem (więc możesz zamknąć terminal i nadal będzie działać)

Te proste kroki pozwolą Ci zamknąć terminal przy jednoczesnym zachowaniu działania procesu.

Nie będzie zakładać nohup (w oparciu o moje zrozumienie twojego pytania, nie potrzebujesz go tutaj).

 1
Author: hi-zir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-20 16:00:33

To działało dla mnie na Ubuntu linux podczas gdy w tcshell.

  1. CtrlZ to pause it

  2. bg aby uruchomić w tle

  3. jobs Aby uzyskać numer pracy

  4. nohup %n gdzie n jest numerem zadania

 0
Author: eshaya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-13 02:32:58