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
foo
został 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 SIGHUP
do 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
foo
został 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
jobs
i można uzyskać do niego dostęp za pomocą %n
(gdzie n
jest 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 SIGHUP
do 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ż SIGHUP
do procesu.
Teraz disown
usuwa zadanie z listy zadań powłoki, więc wszystkie powyższe podpunkty nie mają już zastosowania (w tym proces wysyłany SIGHUP
przez 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 xterm
lub 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 nohup
drugiej 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 nohup
nie nie wyjąć spod kontroli procesu pracy przez powłokę, a także nie umieścić go w tle (ale ponieważ pierwszy plan nohup
praca 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.
disown
usuwa 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.
nohup
odłącza proces od terminala, przekierowuje jego wyjście nohup.out
i 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).