Wiem, nohup
że jako plik binarny można do niego dotrzeć z dowolnej powłoki. Ale exec
wbudowane prawdopodobnie istnieje w każdej powłoce.
Czy istnieje powód, aby preferować jeden z nich?
Co jest lepsze, ryba czy rower? nohup
i exec
robić różne rzeczy.
exec
zastępuje powłokę innym programem. Używanie exec
w prostym zadaniu w tle nie jest przydatne: exec myprogram; more stuff
zamienia powłokę na myprogram
i dlatego nie działa more stuff
, w przeciwieństwie do tego, myprogram; more stuff
który uruchamia się more stuff
po myprogram
zakończeniu; ale exec myprogram & more stuff
zaczyna się myprogram
w tle, a następnie uruchamia more stuff
, podobnie jak myprogram & more stuff
.
nohup
uruchamia 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 nohup
zabezpiecza 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).
nohup
przekierowuje 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 nohup
nie 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 &
exec firefox
powłoka przestaje działać: została zastąpiona przezfirefox
. Można pomyśleć oexec
połą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,firefox
proces zostanie zakończony. Terminal zauważa, że proces potomny zakończył pracę, a następnie z kolei kończy działanie.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.exec
proces umiera poSIGHUP
otrzymaniu a, alenohup
proces jest kontynuowany.źródło
exec
zastę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.exec smth &
to samo(exec smth) &
, co nie dzieje się?(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.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.źródło
script.sh &
lubexec 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?Nie możesz się
nohup
z tym równaćexec
. Gdy uruchomisz plik wykonywalnynohup
, proces nie zostanie zabity po wylogowaniu (sesja ssh); zwyklenohup
służynice
do uruchamiania procesów o niższym priorytecie.HUP
Sygnał jest umownie sposób terminal ostrzega procesy zależne od wylogowaniaźródło