Jaka jest różnica między nohup a ampersand

242

Zarówno nohup myprocess.out &lub myprocess.out &ustaw myprocess.out, aby działał w tle. Po zamknięciu terminala proces nadal działa. Jaka jest różnica między nimi?

Yarkee
źródło
jakiej powłoki używasz? zachowanie różni się w zależności od muszli
shx2
1
grzmotnąć. I wiem, dlaczego teraz według odpowiedzi @nemo.
Yarkee
@Yarkee, jeśli odpowiedź odpowiada twojemu problemowi, zaznacz pytanie jako zaakceptowane (pole wyboru poniżej głosów odpowiedzi), aby nie krążyło po nim jak bez odpowiedzi. Powinieneś to zrobić dla wszystkich swoich pytań :)
nemo
1
shutdownnależy unikać jako terminu o konkretnym znaczeniu dla Linuksa i należy go zastąpić exit.
Patrizio Bertoni

Odpowiedzi:

316

nohupwyłapuje sygnał rozłączenia (patrz man 7 signal), podczas gdy znak ampersand nie (z wyjątkiem, że powłoka jest skonfigurowana w ten sposób lub w ogóle nie wysyła SIGHUP).

Zwykle po uruchomieniu polecenia przy użyciu &i wychodzeniu z powłoki, powłoka zakończy polecenie podrzędne sygnałem rozłączenia ( kill -SIGHUP <pid>). Można temu zapobiec nohup, ponieważ przechwytuje on sygnał i ignoruje go, aby nigdy nie dotarł do rzeczywistej aplikacji.

Jeśli używasz bash, możesz użyć polecenia shopt | grep hupon aby dowiedzieć się, czy twoja powłoka wysyła SIGHUP do swoich procesów potomnych, czy nie. Jeśli jest wyłączone, procesy nie zostaną zakończone, jak wydaje się, że tak jest w twoim przypadku. Więcej informacji na temat zamykania aplikacji przez bash można znaleźć tutaj .

Istnieją przypadki, w których nohupnie działa, na przykład, gdy proces rozpocząć ponownie łączy się SIGHUPsygnał, jak ma to miejsce tutaj .

nemo
źródło
Warto zauważyć, że &powoduje to, że podkomenda nie odbiera niektórych sygnałów (np. SIGINT). nohupzasadniczo dodaje SIGHUPdo listy sygnałów, które nie są propagowane.
studgeek
46

myprocess.out &uruchomiłby proces w tle za pomocą podpowłoki. Jeśli bieżąca powłoka zostanie zakończona (powiedzmy przez wylogowanie), wszystkie podpowłoki również zostaną zakończone, więc proces w tle również zostanie zakończony. Komenda nohup ignoruje HUPsygnał, a zatem nawet jeśli bieżąca powłoka zostanie zakończona, podpowłoka myprocess.outbędzie nadal działać w tle. Inną różnicą jest to, że &sam nie przekierowuje stdout / stderr, więc jeśli są jakieś dane wyjściowe lub błędy, są one wyświetlane na terminalu. nohup natomiast przekierowuje stdout / stderr do nohup.outlub $HOME/nohup.out.

amit_g
źródło
6
Biegnę myprocess.out &i wychodzę z muszli. Jednak gdy używam ps aux | grep myprocess.outw innej powłoce, nadal mogę znaleźć „myprocess.out”. Oznacza to, że proces nadal działa, a nie zostać zakończony.
Yarkee
1
@amit_g Podczas zabijania powłoki nadrzędnej za pomocą kill -9nie pojawi się POWIĘKSZENIE, ponieważ wymagałoby to powłoki nadrzędnej do obsługi SIGKILL, czego nie może.
nemo
2
Sprawdź shopt | grep hupon, jak wspomniano w drugiej odpowiedzi.
amit_g
31

Przez większość czasu logujemy się do zdalnego serwera za pomocą ssh. Jeśli uruchomisz skrypt powłoki i wylogujesz się, proces zostanie zabity. Nohup pomaga kontynuować uruchamianie skryptu w tle, nawet po wylogowaniu z powłoki.

Nohup command name &
eg: nohup sh script.sh &

Nohup przechwytuje sygnały HUP. Nohup nie umieszcza zadania automatycznie w tle. Musimy to wyraźnie powiedzieć, używając &

missgeorge
źródło
Dzięki. Nie spodziewałam się twojej odpowiedzi, ale fakt, że tu jest, jest świetny. Odpowiada na pytanie, którego nie zadałem: D
Vaibhav Kaushal
26

Użycie ampersand (&) spowoduje uruchomienie polecenia w procesie potomnym (potomkiem bieżącej sesji bash). Jednak po wyjściu z sesji wszystkie procesy potomne zostaną zabite.

użycie nohup + ampersand (&) zrobi to samo, z tym wyjątkiem, że po zakończeniu sesji rodzic procesu potomnego zostanie zmieniony na „1”, czyli proces „init”, dzięki czemu dziecko nie zostanie zabite.

Michel
źródło
7

Popraw mnie, jeśli się mylę

  nohup myprocess.out &

nohup przechwytuje sygnał rozłączenia, co oznacza, że ​​wyśle ​​proces po zamknięciu terminala.

 myprocess.out &

Proces może zostać uruchomiony, ale zostanie zatrzymany po zamknięciu terminala.

nohup myprocess.out

Proces może uruchomić nawet terminal zamknięty, ale możesz zatrzymać proces, naciskając ctrl+ zw terminalu. Crt+ znie działa, jeśli &istnieje.

John Joe
źródło
2

Polecenie nohup jest narzędziem do maskowania sygnału i przechwytuje sygnał rozłączenia. Gdzie jako ampersand nie łapie sygnałów rozłączenia. Powłoka zakończy polecenie podrzędne sygnałem rozłączenia podczas uruchamiania polecenia za pomocą & i wychodzenia z powłoki. Można temu zapobiec za pomocą nohup, ponieważ przechwytuje on sygnał. Polecenie Nohup przyjmuje sygnał rozłączenia, który jądro może wysłać do procesu i je blokuje. Polecenie Nohup jest pomocne, gdy użytkownik chce uruchomić długo działającą aplikację, wylogować się lub zamknąć okno, w którym proces został zainicjowany. Każde z tych działań zwykle powoduje, że jądro się rozłącza w aplikacji, ale opakowanie typu nohup pozwoli na kontynuowanie procesu. Użycie ampersand spowoduje uruchomienie polecenia w procesie potomnym i tym potomku bieżącej sesji bash. Po wyjściu z sesji wszystkie potomne procesy tego procesu zostaną zabite. Znak ampersand dotyczy kontroli zadania dla aktywnej powłoki. Jest to przydatne do uruchamiania procesu w sesji w tle.

Santosh
źródło
0

W wielu przypadkach gryzą Cię niewielkie różnice między środowiskami. To jest ten, na który ostatnio pobiegłem. Jaka jest różnica między tymi dwoma poleceniami?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

Odpowiedź jest taka sama jak zwykle - to zależy.

nohup przechwytuje sygnał rozłączenia, podczas gdy znak ampersand nie.

Co to jest sygnał rozłączenia?

SIGHUP - zawieszenie wykryte podczas kontrolowania terminala lub śmierć procesu kontrolowania (wartość: 1).

Zwykle po uruchomieniu polecenia za pomocą & i wyjściu z powłoki, powłoka zakończy polecenie podrzędne sygnałem rozłączenia (np. Kill -SIGHUP $ PID). Można temu zapobiec za pomocą nohup, ponieważ przechwytuje on sygnał i ignoruje go, aby nigdy nie dotarł do rzeczywistej aplikacji.

Dobrze, ale jak w tym przypadku zawsze są „ale”. Nie ma różnicy między tymi metodami uruchamiania, gdy powłoka jest skonfigurowana w taki sposób, że w ogóle nie wysyła SIGHUP.

Jeśli używasz bash, możesz użyć polecenia podanego poniżej, aby dowiedzieć się, czy twoja powłoka wysyła SIGHUP do swoich procesów potomnych, czy nie:

~ $ shopt | grep hupon

A ponadto - są przypadki, w których nohup nie działa. Na przykład, gdy proces, który zaczynasz, ponownie łączy sygnał NOHUP (odbywa się to wewnątrz, na poziomie kodu aplikacji).

W opisanym przypadku brak różnic ugryzł mnie, gdy w skrypcie uruchamiającym usługę niestandardową było wywołanie drugiego skryptu, który konfiguruje i uruchamia odpowiednią aplikację bez polecenia nohup.

W jednym środowisku Linuksa wszystko działało sprawnie, w drugim aplikacja została zamknięta, gdy tylko drugi skrypt się zakończył (wykrycie tego przypadku zajęło mi oczywiście dużo więcej czasu, niż mogłoby się wydawać: stuck_out_tongue :).

Po dodaniu nohup jako metody uruchamiania do drugiego skryptu aplikacja działa nadal, nawet jeśli skrypty zostaną zamknięte, a zachowanie to stało się spójne w obu środowiskach.

Devender Goyal
źródło