Dlaczego warto używać „nohup &” zamiast „exec &”

67

Wiem, nohupże jako plik binarny można do niego dotrzeć z dowolnej powłoki. Ale execwbudowane prawdopodobnie istnieje w każdej powłoce.

Czy istnieje powód, aby preferować jeden z nich?

loxaxs
źródło

Odpowiedzi:

113

Co jest lepsze, ryba czy rower? nohupi execrobić różne rzeczy.

execzastępuje powłokę innym programem. Używanie execw prostym zadaniu w tle nie jest przydatne: exec myprogram; more stuffzamienia powłokę na myprogrami dlatego nie działa more stuff, w przeciwieństwie do tego, myprogram; more stuffktóry uruchamia się more stuffpo myprogramzakończeniu; ale exec myprogram & more stuffzaczyna się myprogramw tle, a następnie uruchamia more stuff, podobnie jak myprogram & more stuff.

nohupuruchamia określony program z ignorowanym sygnałem SIGHUP. Kiedy terminal jest zamknięty, jądro wysyła SIGHUP do procesu kontrolnego w tym terminalu (tj. Powłoce). Z kolei powłoka wysyła SIGHUP do wszystkich zadań działających w tle. Uruchomienie zadania z nohupzabezpiecza go przed zabiciem w ten sposób, jeśli terminal umrze (co dzieje się na przykład, jeśli użytkownik był zalogowany zdalnie i połączenie zostało zerwane lub jeśli zamknięto emulator terminalu).

nohupprzekierowuje również wyjście programu do pliku nohup.out. Dzięki temu program nie umiera, ponieważ nie jest w stanie zapisać danych wyjściowych ani błędów. Zauważ, że nohupnie przekierowuje wejścia. Aby całkowicie odłączyć program od terminala, w którym został uruchomiony, użyj

nohup myprogram </dev/null >myprogram.log 2>&1 &
Gilles
źródło
27
rower> ryba
Chris Jaynes
6
Pozwolę sobie być innego zdania. Ryby są oczywiście lepszą metodą transportu, jeśli można je wdrożyć.
TEN UŻYTKOWNIK POTRZEBUJE POMOCY
6
@THISUSERNEEDSHELP Ale rower to na pewno lepsze jedzenie?
Gilles
3
@GypsyCosmonaut Po uruchomieniu exec firefoxpowłoka przestaje działać: została zastąpiona przez firefox. Można pomyśleć o execpołączeniu wyjścia z programu i uruchomieniu nowego, ale z zachowaniem tego samego identyfikatora procesu. Terminal pracuje cały czas, bo nic nie powiedział jej, aby zatrzymać. Gdy później zamkniesz Firefoksa, firefoxproces zostanie zakończony. Terminal zauważa, że ​​proces potomny zakończył pracę, a następnie z kolei kończy działanie.
Gilles
5
Daj człowiekowi rybę, a będziesz go karmić przez jeden dzień. Daj człowiekowi rower, a będzie mógł jeździć nim do supermarketu i kupować ryby na całe życie.
David
18

exec & => wykonuje proces jako proces w tle, więc możesz nadal używać tego samego terminala do innych zadań.

nohup => unika wszystkich SIGHUP (zakończenie sygnału) i kontynuuje wykonywanie, nawet jeśli terminal jest zamknięty.

execproces umiera po SIGHUPotrzymaniu a, ale nohupproces jest kontynuowany.

Ani Menon
źródło
1
Ta odpowiedź wydaje się poprawna. Jak mówią inne odpowiedzi powyżej, zwykle execzastępuje uruchomiony proces, ale wydaje się, że tak się nie dzieje, gdy użyjesz &tła do wykonania polecenia exec'd. Ani w bash, ani w zsh.
Dan Pritts,
@DanPritts Co masz na myśli mówiąc, że tak się nie dzieje? Podproces tła jest uruchamiany, a następnie zastępowany, więc exec smth &to samo (exec smth) &, co nie dzieje się?
phk
1
Mam na myśli, że nie wykonuje się go w tym sensie, o jakim normalnie byś pomyślał (zastępując bieżącą działającą powłokę) - po prostu działa jako proces w tle. Myślę, że prawdopodobnie jest taki sam jak (exec smth) &. Ale nie spodziewałbym się, że będzie tak samo - oczekiwałbym, że będzie to błąd składniowy, w jaki sposób możesz wykonać proces (zastępując siebie), a następnie wykonać proces exec w tle? Już cię tam nie ma.
Dan Pritts
2

Wbudowane polecenie exec <command>powłoki zastępuje powłokę <command>, nie ma nowego procesu, nie jest tworzony nowy PID. Po zakończeniu <command>normalnie twój terminal zostanie zamknięty. Uruchamiając go w tle, najpierw tworzona jest podpowłoka, która następnie podobnie jest natychmiast zastępowana przez <command>.

nohup <command> Komenda uruchomi <command>ale immume do hangups (kill -s 1), więc to nie zostanie zakończone, gdy powłoka, terminal, z którego został rozpoczęty jest zamknięty. Po uruchomieniu go w tle najpierw tworzona jest podpowłoka, a polecenie działa w tle, co powoduje powrót do monitu.

W skryptach natychmiastowy efekt jest mniej więcej taki sam, <command>jest uruchamiany przez skrypt i skrypt będzie kontynuował bez oczekiwania na <command>rozpoczęcie, wysłanie danych wyjściowych lub zakończenie.

HBruijn
źródło
Ja też nie jestem pewien, co robi exec. Mam na myśli… Rozumiem, co to ma robić, ale widzę tylko niewielką różnicę między robieniem script.sh &lub exec script.sh &. W obu przypadkach polecenie jest wykonywane w procesie potomnym, nie zastępuje procesu wywołującego, patrz: paste.alacon.org/44474 (zbyt długo, aby skopiować go tutaj w komentarzu…). Co ja robię źle?
Stéphane,
2

Nie możesz się nohupz tym równać exec. Gdy uruchomisz plik wykonywalny nohup, proces nie zostanie zabity po wylogowaniu (sesja ssh); zwykle nohupsłuży nicedo uruchamiania procesów o niższym priorytecie. HUPSygnał jest umownie sposób terminal ostrzega procesy zależne od wylogowania

użytkownik2660420
źródło