Różnica między nohup, disown i &

579

Jakie są różnice między

$ nohup foo

i

$ foo &

i

$ foo & 
$ disown
lesmana
źródło
50
Zaraz, możesz się wyrzucić bez podawania PID? Wspaniały!
ripper234,
34
Jest też foo &!coś, co powinno być równoznaczne z odrzuceniem go od samego początku.
user4514,
26
Bash nie obsługuje & !.
Jonas Kongslund
20
foo & disownwyprzeć się natychmiast.
ctrl-alt-delor
9
Chciałbym zobaczyć wzmiankę o setsid, i jak odnosi się do disowninohup
YoungFrog

Odpowiedzi:

558

Przyjrzyjmy się najpierw, co się stanie, jeśli program zostanie uruchomiony z interaktywnej powłoki (podłączonej do terminala) bez &(i bez przekierowania). Załóżmy więc, że właśnie wpisałeś foo:

  • Uruchomiony proces foozostał utworzony.
  • Proces dziedziczy stdin, stdout i stderr z powłoki. Dlatego jest również podłączony do tego samego terminala.
  • Jeśli powłoka otrzyma a SIGHUP, wysyła również a SIGHUPdo procesu (co normalnie powoduje zakończenie procesu).
  • W przeciwnym razie powłoka czeka (jest blokowana), aż proces się zakończy.

Teraz spójrzmy, co się stanie, jeśli umieścisz proces w tle, czyli wpisz foo &:

  • Uruchomiony proces foozostał utworzony.
  • Proces dziedziczy stdout / stderr z powłoki (więc nadal zapisuje na terminalu).
  • Proces w zasadzie również dziedziczy stdin, ale gdy tylko próbuje odczytać ze stdin, zostaje zatrzymany.
  • Zostaje umieszczony na liście zadań w tle zarządzanych przez powłokę, co oznacza w szczególności:
    • Jest wymieniony na liście jobsi można uzyskać do niego dostęp za pomocą %n(gdzie njest numer zadania).
    • Można go przekształcić w zadanie pierwszoplanowe fg, w którym to przypadku jest kontynuowane, jakbyś nie używał &go (a jeśli został zatrzymany z powodu próby odczytu ze standardowego wejścia, może teraz kontynuować czytanie z terminala).
    • Jeśli powłoka otrzymała a SIGHUP, wysyła również a SIGHUPdo procesu. W zależności od powłoki i ewentualnie opcji ustawionych dla powłoki, po zakończeniu powłoki wyśle ​​ona również SIGHUPdo procesu.

Teraz disownusuwa zadanie z listy zadań powłoki, więc wszystkie powyższe podpunkty nie mają już zastosowania (w tym proces wysyłany SIGHUPprzez powłokę). Należy jednak pamiętać, że nadal jest podłączony do terminala, więc jeśli terminal zostanie zniszczony (co może się zdarzyć, jeśli był to pty, taki jak utworzony przez xtermlub ssh, a program sterujący zostanie zakończony, zamykając xterm lub kończąc połączenie SSH ) , program zawiedzie, gdy tylko spróbuje odczytać ze standardowego wejścia lub zapisać na standardowe wyjście.

Z nohupdrugiej strony chodzi o skuteczne oddzielenie procesu od terminala:

  • Zamyka standardowe wejście (program nie będzie w stanie odczytać żadnego wejścia, nawet jeśli zostanie uruchomiony na pierwszym planie. Nie zostanie zatrzymany, ale otrzyma kod błędu lub EOF).
  • Przekierowuje standardowe wyjście i standardowy błąd do pliku nohup.out, więc program nie zawiedzie w przypadku zapisu na standardowe wyjście, jeśli terminal ulegnie awarii, więc wszystko, co pisze proces, nie zostanie utracone.
  • Uniemożliwia to procesowi otrzymanie SIGHUP(stąd nazwy).

Zauważ, że nohupnie nie wyjąć spod kontroli procesu pracy przez powłokę, a także nie umieścić go w tle (ale ponieważ pierwszy plan nohuppraca jest mniej lub bardziej bezużyteczny, którą zazwyczaj umieścić go w tle przy użyciu &). Na przykład, inaczej niż w przypadku disown, powłoka nadal powie ci, kiedy zadanie nohup zakończy się (chyba że powłoka została wcześniej zakończona, oczywiście).

Podsumowując:

  • & umieszcza zadanie w tle, co oznacza, że ​​blokuje ono próbę odczytu danych wejściowych i sprawia, że ​​powłoka nie czeka na zakończenie.
  • disownusuwa proces z kontroli zadań powłoki, ale nadal pozostawia ją podłączoną do terminala. Jednym z rezultatów jest to, że powłoka nie wyśle ​​jej SIGHUP. Oczywiście można go zastosować tylko do zadań w tle, ponieważ nie można go wprowadzić, gdy uruchomione jest zadanie pierwszego planu.
  • nohupodłącza proces od terminala, przekierowuje jego wyjście nohup.outi osłania go SIGHUP. Jednym z efektów (nazewnictwa) jest to, że proces nie otrzyma żadnego wysłanego SIGHUP. Jest całkowicie niezależny od kontroli zadań i może być zasadniczo stosowany również do zadań na pierwszym planie (choć nie jest to bardzo przydatne).
celtschk
źródło
8
+1 dzięki. Co się wtedy stanie, gdy użyjesz disown, nohup i & razem?
Tim
15
Jeśli użyjesz wszystkich trzech razem, proces działa w tle, jest usuwany z kontroli zadań powłoki i jest skutecznie odłączany od terminala.
celtschk
1
jaka jest różnica między disown %1i disown -h %1? Drugi zachowa się jako normalne zadanie (ale ignoruje sygnał HUP), dopóki terminal nie wyjdzie?
schemacs
4
Może warto (foo&)
włączyć
169

Użycie &powoduje, że program działa w tle, więc zamiast blokowania do momentu zakończenia programu pojawi się nowy monit powłoki. nohupi disownsą w dużej mierze niezwiązane; tłumią sygnały SIGHUP (rozłączenia), aby program nie był automatycznie zabijany po zamknięciu terminala sterującego. nohuprobi to, gdy praca zaczyna się po raz pierwszy. Jeśli nie nohuprozpoczniesz zadania, możesz disownzmodyfikować uruchomione zadanie; bez argumentów modyfikuje bieżące zadanie, które właśnie zostało w tle

Michał Mrożek
źródło
10
Niewielka różnica między nohup a disown: polecenie disown usunie go z listy zadań; nohup nie będzie.
Shawn J. Goff,
191
nohupi disownoba można tłumić SIGHUP, ale na różne sposoby. nohuppowoduje, że program początkowo ignoruje sygnał (program może to zmienić). nohupPróbuje również tak ustawić program, aby nie miał terminalu sterującego, aby nie był wysyłany SIGHUPprzez jądro, gdy terminal jest zamknięty. disownjest czysto wewnętrzny względem powłoki; powoduje, że powłoka nie wysyła SIGHUPpo zakończeniu.
Gilles
27
@Gilles, twój komentarz jest wart własnej odpowiedzi.
lesmana,
5
Tylko wyjaśnienie komentarza @ ShawnJ.Goff dotyczącego disownusuwania zadania z listy zadań. Jeśli nie określisz opcji, spowoduje to usunięcie jej z listy zadań. Jednakże , jeśli podasz -hopcję, każdy jobspec jest nie usunięty z tabeli. Zamiast tego sprawia, że SIGHUPnie jest wysyłany do zadania, jeśli powłoka otrzyma polecenie SIGHUP.
tacot Tuesday
4
Właśnie w celu wyjaśnienia, używając &nie daje terminal, odłącza stdinod procesu i powoduje go uruchomić w tle, ale oba stdouti stderrnadal jest załączony do aktualnej konsoli. Oznacza to, że możesz pomieszać tekst z różnych programów, co może być dość irytujące, jeśli to zrobisz gimp &i pojawi się wiele błędów GTK + podczas próby użycia tego tty do czegoś innego.
Frank
8

Oto moje doświadczenie w próbie uruchomienia biura w tle, po wykonaniu polecenia nie kończącego (np tail.). W tym przykładzie użyję sleep 100.

I

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

I zobaczyć soffice logi / naciskając Ctrl- Cprzystanki soffice

nohup .. i

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Nie widzę dzienników soffice / naciskając Ctrl- Csoffice zatrzymuje się

i wyrzucić

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

I zobaczyć soffice logi / naciskając Ctrl- Cprzystanki soffice

setsid .. i

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

I zobaczyć soffice dzienniki / naciskając Ctrl- Csoffice nie zatrzymuje

Aby zaoszczędzić miejsce::
nohup setsid ..nie wyświetla dzienników / poddasza NIECtrlC ZATRZYMUJE się na -
nohup z & disownna końcu: nie pokazuje dzienników / poddasza zatrzymuje się Ctrl-C

Marinos An
źródło
2
Chociaż doceniam wysiłek wspominania setida i pokazania, co dzieje się w tej konkretnej sytuacji, chciałbym zobaczyć dokładniejszą odpowiedź. W szczególności różnica i podobieństwo każdego rozwiązania, zarówno widoczne (co dzieje się po zamknięciu powłoki lub terminala, dokąd idzie wyjście, ...) i niewidoczne (jak to się dzieje pod maską i ich implikacje). Przyjęta odpowiedź jest na to dobrą bazą.
YoungFrog
1
@YoungFrog Zgodzę się na to!
Marinos An
Dla mnie nohup ⟨command⟩ & disownstworzony proces nie kończy się na Ctrl+C.
k.stm
@ k.stm Próbowałeś soffice? sofficepolecenie wydaje się mieć coś innego. Rozważyłem więc dodanie go tutaj jako wyjątku od reguły. np. przy użyciu: nohup .. &naciśnięcie Ctrl-cnormalnie nie powoduje zatrzymania polecenia, ale sofficepowoduje to. Czekam, aż ktoś podejdzie do tego i wyjaśni, dlaczego tak się dzieje z biurowcem :)
Marinos An
@Marinos Tak, zrobiłem. Pobiegłem nohup soffice &i nacisnąłem Ctrl+C. Nic się nie stało, zgodnie z oczekiwaniami.
k.stm