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?)
10 answers
Użycie kontroli zadania bash do wysłania procesu w tło:
- Ctrl+Z aby zatrzymać (wstrzymać) program i wrócić do powłoki.
-
bg
aby uruchomić go w tle. -
disown -h [job-spec]
Gdzie [job-spec] jest numerem zadania (jak%1
dla pierwszego uruchomionego zadania; Znajdź numer za pomocą poleceniajobs
), aby zadanie nie zostało zabite po zamknięciu terminala.
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.
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
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.
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.
nohup
, która może być zastosowana do uruchomionego procesu:
nohup -p pid
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.
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
Run some SOMECOMMAND, powiedz
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl+Z aby zatrzymać (wstrzymać) program i wrócić do powłoki.
bg
aby uruchomić go w tle.disown -h
aby proces nie został zabity, gdy terminal się zamyka.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
.
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.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
- ctrl + z - spowoduje to wstrzymanie pracy(nie będzie anulować!)
-
bg
- spowoduje to umieszczenie zadania w tle i zwrócenie w uruchomionym procesie -
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).
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.
-
CtrlZ to pause it
-
bg
aby uruchomić w tle -
jobs
Aby uzyskać numer pracy -
nohup %n
gdzie n jest numerem zadania
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