Odpowiedzi:
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 przez firefox
. Można pomyśleć o exec
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 po SIGHUP
otrzymaniu a, ale nohup
proces jest kontynuowany.
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.
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?
Nie możesz się nohup
z tym równać exec
. Gdy uruchomisz plik wykonywalny nohup
, proces nie zostanie zabity po wylogowaniu (sesja ssh); zwykle nohup
służy nice
do uruchamiania procesów o niższym priorytecie. HUP
Sygnał jest umownie sposób terminal ostrzega procesy zależne od wylogowania