Po zalogowaniu się ssh
wpisuję to polecenie w bash
:
sleep 50000000000000 &
Potem kill -9
przez sleep
proces macierzysty procesu (tj bash
). Następnie okno terminala rozłącza się jednocześnie.
Gdy loguję się ponownie, okazuje się, że sleep
proces jest nadal aktywny.
Pytanie : Dlaczego sleep
proces może przetrwać, gdy się wyloguję, a terminal zostanie zamknięty? Moim zdaniem wszystko oprócz demonów i nohup
programów zostanie zabite podczas wylogowywania. Jeśli sleep
mogę przetrwać w ten sposób, czy to oznacza, że mogę użyć tej metody zamiast nohup
polecenia?
&
rozwinie proces na tło (jak demon) i będzie działał mimo wylogowania.Odpowiedzi:
Tl; dr:
O ile
bash
instancja spawnowana przezssh
nie mahuponexit
ustawionej opcji, żaden proces nie zostanie w żaden sposób zakończony po wyjściu / wylogowaniu, a gdyhuponexit
opcja jest ustawiona, użyciekill -9
w powłoce nie jest dobrą alternatywą dla użycianohup
w procesach potomnych powłoki;nohup
na procesach potomnych powłoki nadal ochroni je przed SIGHUPami, które nie pochodzą z powłoki, i nawet jeśli nie jest to ważne,nohup
nadal jest preferowane, ponieważ pozwala na pełne zakończenie działania powłoki.W
bash
istnieje opcja o nazwiehuponexit
, która jeśli zestaw sprawibash
SIGHUP jego dzieci po wyjściu / wylogowania;W interaktywnych bez logowania
bash
przypadkach, takich jak nabash
przykład wywoływanych przezgnome-terminal
ta opcja jest ignorowana; niezależnie od tego, czyhuponexit
jestbash
uzbrojony czy rozbrojony, dzieci nigdy nie zostaną ZWIĘKSZONEbash
przy wyjściu;W interaktywnych instancjach logowania
bash
, takich jakbash
instancja spawnowana przezssh
, ta opcja nie jest ignorowana (jednak domyślnie jest rozbrojona); jeślihuponexit
jest ustawione,bash
dzieci będą PODNIESIANE przezbash
przy wyjściu / wylogowaniu; jeślihuponexit
jest rozbrojone,bash
dzieci nie będą PODNIESIANE przezbash
przy wyjściu / wylogowaniu;Ogólnie rzecz biorąc, wychodzenie / wylogowywanie się z interaktywnego
bash
wystąpienia logowania , chyba żehuponexit
opcja jest ustawiona, nie spowoduje, że powłoka ZATRZYMUJE swoje potomne, a wyjście / wylogowanie z interaktywnegobash
wystąpienia niezalogowanego nie sprawi, że powłoka ZRÓB SIĘ jego potomkami bez względu;Nie ma to jednak znaczenia w tym przypadku: używanie
kill -9
sleep
przetrwa niezależnie, ponieważ zabicie jego procesu nadrzędnego (bash
) nie pozostawi szansy temu drugiemu na zrobienie czegokolwiek z tym pierwszym (tj. Np. Jeśli bieżącabash
instancja byłabash
instancją logowania i ustawionohuponexit
opcję, aby ją PODSUMOWAĆ).Dodatkowo, w przeciwieństwie do innych sygnałów (takich jak wysyłany do SIGNUP sygnał
bash
), sygnał SIGKILL nigdy nie jest propagowany do procesów potomnych procesu, a zatemsleep
nawet nie zostaje zabity;nohup
rozpoczyna proces odporny na sygnały SIGHUP, co jest czymś innym; zapobiegnie zawieszeniu się procesu po odebraniu sygnału SIGHUP, który w tym przypadku mógłby zostać odebrany przezbash
instancję interaktywnego logowania, jeślihuponexit
opcja została ustawiona i powłoka została zamknięta; więc technicznie użycienohup
do uruchomienia procesu w interaktywnejbash
instancji logowania zhuponexit
wyłączoną opcją zapobiegnie zawieszeniu się procesu po odebraniu sygnału SIGHUP, ale wyjście / wylogowanie z powłoki nie ZNAJDUJE go niezależnie;Zasadniczo jednak, gdy
nohup
jest to potrzebne, aby zapobiec nadejściu sygnałów SIGHUP z powłoki nadrzędnej, nie ma powodu, aby preferowaćkill -9
metodę nadrzędnąnohup
nad metodą podrzędną; zamiast tego powinno być odwrotnie.Zabicie rodzica za pomocą
kill -9
metody nie pozostawia rodzicowi wdzięcznego wyjścia, podczas gdy uruchomienie dziecka za pomocąnohup
metody pozwala rodzicowi zostać zakończonym przez inne sygnały, takie jak SIGHUP (na przykład, który ma sens w kontekście dziecka zaczęło używaćnohup
), co pozwala mu z wdziękiem wyjść.źródło
ps -e | grep process
powinieneś wymienić proces wraz z PID (lub lepiej,pgrep -x process
jeśli na pewno dopasujesz ten pojedynczy proces, a nie niepotrzebne rzeczy); problem polega na tym, że kiedy zabijesz proces, gdykill -9
jego dzieci stają się własnościąupstart
, dlatego ich pierwotny PPID zostaje utracony, a ich PPID zmienia się na PID upstartu, co czyni je nierozpoznawalnymi (AFAIK), ale z powodu ich nazwy lub PIDnohup
nie uda się zapobiec zawieszeniu się procesu po otrzymaniu sygnału SIGHUP z procesu nadrzędnego? Próbuję uruchomić proces w tle (w terminalu powłoki PuTTY SSH) przeznohup <command> <arg> &
. Kiedy wyloguję się, klikającX
przycisk PuTTY , proces w tle zostanie natychmiast zakończony. Gdy wyloguję się, wpisującexit
terminal powłoki PuTTY SSH, proces będzie kontynuowany w tle.bash
domyślnie nie wysyła sygnału HUP do procesów potomnych podczas wychodzenia . Bardziej szczegółowo (dzięki @kos), nigdy nie robi tego w przypadku powłok niezalogowanych .Możesz skonfigurować bash, aby robił to dla powłok logowania, jeśli ustawiłeś opcję
huponexit
. W terminalu wykonaj:(uruchomi to nową powłokę „login”)
Teraz sprawdź
sleep
proces:... nie działa: odebrał sygnał HUP i zakończył działanie zgodnie z żądaniem.
źródło
sleep 1000 & ; exit
tosleep
przetrwa? Zauważ, że jeśli ja proces to będzie wyjść. I nawet jeśli jest ustawiony, przetrwa. Mylić ... (Postaram się lepiej zrozumieć i zmodyfikować odpowiedź, w przeciwnym razie usunę ją).kill -HUP
sleep
huponexit
sleep
kill -9
tak naprawdę nie należy tego robić. To jak strzelanie z pistoletu w telewizor, żeby go wyłączyć. Oprócz elementu komediowego nie ma przewagi. Procesy nie mogą złapać ani zignorowaćSIGKILL
. Jeśli nie dasz temu procesowi szansy na ukończenie tego, co robi i wyczyszczenia, może pozostawić uszkodzone pliki (lub inny stan) w pobliżu i nie będzie można rozpocząć od nowa.kill -9
jest ostatnią nadzieją, kiedy nic innego nie działa.Co w twoim przypadku się dzieje:
Proces nadrzędny
sleep
to aktualnie działającabash
powłoka. Kiedykill -9
to bash, proces bash nie ma szansy wysłaćSIGHUP
żadnego z jego procesów potomnych, ponieważSIGKILL
(który jest wysyłany przezkill -9
) proces nie może go wyłapać. Proces uśpienia jest kontynuowany. sen stał się teraz procesem osieroconym .Proces init (PID 1) wykonuje mechanizm zwany reparenting. Oznacza to, że proces init staje się teraz rodzicem tego osieroconego procesu. init jest wyjątkiem, procesy mogą stać się jego potomkami, ponieważ gromadzą procesy, które utraciły swój pierwotny proces nadrzędny. Btw: Demon (jak
sshd
) robi to, gdy „idzie w tle”.Gdyby tak się nie stało, osierocony proces stałby się później (po zakończeniu) procesem zombie. Dzieje się tak, gdy
waitpid()
nie jest wywoływany (odpowiedzialność procesu nadrzędnego, którego nie można wypełnić, gdy proces ten zostanie zabity). wywołania initwaitpid()
w określonych odstępach czasu, aby uniknąć dzieci zombie.źródło
TERM
lubHUP
huponext
. I TERM poczeka, aż sen się skończy. W przypadku polecenia uśpienia PO byłoby to tysiące lat =)&
Rozpoczyna proces w tle. Jeśli wpiszeszps -ef
, zobaczysz, że nadrzędny identyfikator procesu (PPID) twojego snu to twoja bash. Następnie wyloguj się i zaloguj ponownie. Proces pozostanie uruchomiony po wylogowaniu. Po zalogowaniu się po raz drugi uruchomps -ef
ponownie. Zobaczysz, że teraz rodzicem twojego procesu snu będzie proces o identyfikatorze „1”. To jest init, rodzic wszystkich procesów.źródło
Użycie
&
spowoduje uruchomienie programu w tle. Aby zobaczyć program w tle, użyjbg
komendy i uruchom go ponownie jako pierwszy plan, uruchomfg
.Tak, istnieje wiele sposobów na utrzymanie działania programu, nawet gdy główny terminal jest zamknięty.
źródło
huponexit
działa tylko na powłoki logowania, takie jak powłoka uzyskana przezssh
(a nie, powiedzmy, w powłoce uzyskanej przezgnome-terminal
)