Czy „disown -h” i „nohup” działają tak samo skutecznie?

18

disown

  • powoduje, że powłoka nie wysyła SIGHUP do odrzuconego zadania, gdy powłoka się kończy, oraz

  • usuwa odrzucone zadanie z kontroli zadań powłoki.

Czy pierwszy jest wynikiem drugiego? Innymi słowy, jeśli proces rozpoczęty od powłoki zostanie w jakikolwiek sposób usunięty z kontroli zadań powłoki, czy powłoka nie wyśle ​​SIGHUP do procesu, gdy powłoka się zakończy?

disown -h nadal utrzymuje proces pod kontrolą zadania powłoki. Czy to oznacza, disown -hże proces nadal otrzymuje SIGHUP wysyłane z powłoki, ale ustawia akcję SIGHUP przez proces, aby był „ignorowany”? Brzmi podobnie do nohup.

$ sleep 123 & disown -h
[1] 26103
$ jobs
[1]+  Running                 sleep 123 &
$ fg 1
sleep 123
$ ^Z
[1]+  Stopped                 sleep 125
$ bg 1
[1]+ sleep 123 &
$ exit

$ ps aux | grep sleep
t        26103  0.0  0.0  14584   824 ?        S    15:19   0:00 sleep 123

Czy disown -hi nohupdziałaj skutecznie tak samo, jeśli pominiemy ich różnicę w korzystaniu z terminala?

Dzięki.

Tim
źródło
Inną różnicą nie omawianą tutaj jest to, że jeśli nie używasz nohup, musisz przekierować stdin / stdout / stderr z dala od TTY (jeśli twoja oryginalna powłoka jest podłączona do jednego). (OTOH, tak naprawdę uważam, że to lepsza praktyka niż poleganie na skandalicznych domyślnych ustawieniach, takich jak ./nohup.out).
Charles Duffy

Odpowiedzi:

21

nohupi disown -hnie są dokładnie tym samym.

Za disownpomocą proces jest usuwany z listy zadań w bieżącej powłoce interaktywnej. Uruchomienie jobspo uruchomieniu procesu w tle i uruchomienie disownnie pokaże tego procesu jako zadania w powłoce. Odrzucone zadanie nie otrzyma HUPod powłoki po wyjściu (ale patrz uwaga na końcu).

Za pomocą disown -h, zadanie nie jest usuwane z listy zadań, ale powłoka nie wysyłałaby HUPdo niego sygnału, gdyby się zakończył (ale patrz uwaga na końcu).

nohupNarzędzie ignoruje HUPsygnał i zaczyna daną użyteczność. Narzędzie dziedziczy maskę sygnału nohupi dlatego również zignoruje HUPsygnał. Kiedy powłoka się kończy, proces pozostaje procesem potomnym nohup(i nohupjest ponownie rodzicielski init).

Różnica polega na tym, że proces rozpoczął się od nohupignorowania, HUPniezależnie od tego, kto wysyła sygnał. W wyparł procesy nie są właśnie wysyłane do HUPsygnału przez powłokę , ale nadal może być wysłany sygnał z np kill -s HUP <pid>i nie będzie zignorować.

Zauważ, że HUPjest wysyłane tylko do zadań powłoki, jeśli

  • powłoka jest powłoką logowania i ustawiono huponexitopcję powłoki, lub
  • sama skorupa odbiera HUPsygnał.

Odpowiednie fragmenty bashinstrukcji (moje podkreślenie):

SYGNAŁY

[...]

Powłoka wychodzi domyślnie po otrzymaniuSIGHUP . Przed wyjściem interaktywna powłoka ponownie wysyła SIGHUPdo wszystkich zadań, uruchomionych lub zatrzymanych. Zatrzymane zadania są wysyłane w SIGCONTcelu zapewnienia, że ​​otrzymają SIGHUP. Aby zapobiec wysyłaniu przez powłokę sygnału do określonego zadania, należy ją usunąć z tabeli zadań z disownwbudowanym (patrz SHELL BUILTIN COMMANDSponiżej) lub zaznaczyć, że nie można jej SIGHUP użyć disown -h.

Jeśli ustawiono huponexitopcję powłoki shopt, bashwysyła a SIGHUPdo wszystkich zadań po wyjściu z powłoki logowania interaktywnego.

disown [-ar] [-h] [jobspec ... | pid ... ]

Bez opcji usuń każdą jobspecz tabeli aktywnych zadań. [...] Jeśli -hpodano opcję, każda z nich niejobspec jest usuwana z tabeli, ale jest oznaczana, aby SIGHUPnie była wysyłana do zadania, jeśli powłoka otrzyma komunikatSIGHUP . [...]

Związane z:

Kusalananda
źródło
Dostaję to bash: disown: nohup: no such jobsamo za sleepi 5od disown nohup sleep 5 &. Co miałeś na myśli przez to drugie polecenie z ostatniego zdania?
Ruslan
@ Ruslan Tak. Brakuje mi &tam (i kolejność nohupi disownbyła również błędna). Dzięki. Zaktualizuje się teraz.
Kusalananda
@Tim Przepraszamy za nadmierną edycję odpowiedzi. Minęło trochę czasu, zanim udało mi się to obejść. Skończyłam teraz.
Kusalananda
Dzięki. disownsprawia, że ​​powłoka nie wysyła SIGHUP do dziecka, usuwając dziecko z listy zadań powłoki. Jak to disown -hosiągnąć?
Tim
4

Oni są różni:

  • disown usuwa zadanie z tabeli aktywnych zadań. Następnie kontynuuje bieżącą pracę. Z opcją -h proces NIE jest wysyłany ZWIĘKSZENIE. Zamiast tego pozostaje umrzeć wraz ze skorupą, która go zawiera, gdy otrzyma POWIĘKSZENIE.

  • nohup ignoruje HUP. Następnie wszystko, co zostałoby przekazane do terminala przez zamknięcie procesu, przechodzi do pliku nohup.out.

    nohup jest zdefiniowany przez POSIX, a disown nie.

Michael Prokopec
źródło
Co masz na myśli mówiąc „umrzyj z powłoką, która go zawiera”? Zabicie procesu rodzica samo w sobie nie zabija dziecka. Programy, których terminale są zamknięte, zwykle giną z powodu awarii związanych z próbami interakcji z uchwytem pliku dołączonym do PTY terminala, ale jeśli stdin / stdout / stderr zostaną przekierowane gdzie indziej, to się nie zdarzy.
Charles Duffy