Навіщо використовувати "nohup &", а не "exec &"


67

Я знаю, що, nohupбудучи двійковим, до нього можна дістатися з будь-якої оболонки. Але execвбудований, мабуть, є в кожній оболонці.

Чи є причина віддати перевагу одному з них, а не іншому?

Відповіді:


113

Що краще, риба чи велосипед? nohupі execробити різні речі.

execзамінює оболонку іншою програмою. Використання execв простому фоновому завданні не корисно: exec myprogram; more stuffзамінює оболонку myprogramі не працює more stuff, на відміну від myprogram; more stuffзапуску, more stuffколи myprogramприпиняється; але exec myprogram & more stuffпочинається myprogramна задньому плані, а потім працює more stuff, так само, як myprogram & more stuff.

nohupзапускає конкретну програму з ігнорованим сигналом SIGHUP. Коли термінал закритий, ядро ​​відправляє SIGHUP до керуючого процесу в цьому терміналі (тобто оболонці). Оболонка в свою чергу посилає SIGHUP на всі завдання, що виконуються у фоновому режимі. Запуск роботи з nohupне дозволяє вбити її таким чином, якщо термінал загине (що трапляється, наприклад, якщо ви ввійшли в систему дистанційно і припинилося з'єднання, або якщо ви закриєте емулятор терміналу).

nohupтакож переспрямовує вихід програми у файл nohup.out. Це дозволяє уникнути загибелі програми, оскільки вона не в змозі записати на свій вихід або помилку. Зверніть увагу, що nohupвхід не перенаправляє. Щоб повністю відключити програму від терміналу, де ви її запустили, використовуйте

nohup myprogram </dev/null >myprogram.log 2>&1 &

27
a bicycle> a fish
Chris Jaynes

6
Дозволю собі не погодитися. Риба, очевидно, є найкращим способом транспортування, якщо її можна реалізувати.
ЦЕ ПОТРІБНИК ПОТРІБНО ДОПОМОГА

6
@THISUSERNEEDSHELP Але, напевно, велосипед - це краща їжа?
Жиль

3
@GypsyCosmonaut Після запуску exec firefoxоболонка більше не працює: її замінено на firefox. Можна подумати execяк поєднання виходу з програми та запуску нової, але збереження того ж ідентифікатора процесу. Термінал продовжує працювати , тому що нічого не сказав це зупинити. Після пізнього виходу з Firefox firefoxпроцес припиняється. Термінал помічає, що його дочірній процес закінчився, і тому він закінчується по черзі.
Жиль

5
Дайте чоловікові рибу, і ви годуєте його на день. Дайте людині велосипед, і він може їздити на ньому до супермаркету і купувати рибу на все життя.
Давид

18

exec & => виконує процес як фоновий процес, щоб ви могли продовжувати використовувати той же термінал для інших завдань.

nohup => уникає всіх SIGHUP (сигнал завершення) і продовжує виконання, навіть якщо термінал закритий.

execпроцес вмирає, коли SIGHUPотримано a , але nohupпроцес триває.


1
Ця відповідь видається правильною. Як говорять інші відповіді вище, зазвичай execзамінює запущений процес, але це, здається, не відбувається, коли ви використовуєте &для тла команди exec'd. Ні в баш, ні в шш.
Dan Pritts

@DanPritts Що ви маєте на увазі з цим не відбувається? Фоновий підпроцес запускається, а потім замінюється, exec smth &це те саме, що (exec smth) &, чи не так?
phk

1
Я маю на увазі, що це не виконується в тому сенсі, про який ви зазвичай думаєте (замінюючи поточну запущену оболонку) - вона просто запускається як фоновий процес. Я думаю, це, мабуть, те саме, що (exec smth) &. Але я не очікував би, що це буде однаково - я б очікував, що це синтаксична помилка, як ви можете виконати процес (замінивши себе), а потім перетворити фоновий процес у exec'd? Ти більше не для цього.
Dan Pritts

2

Оболонка, вбудована в команду, exec <command>замінює оболонку <command>, не створюється новий процес, не створюється новий PID. Після завершення роботи <command>ваш термінал закриється. Запустивши його у фоновому режимі, спочатку створюється підшалл, який потім аналогічно відразу замінюється <command>.

nohup <command> Команда буде працювати , <command>але immume , щоб вбити зависання (-S 1) , тому він не буде припинений , коли оболонка, термінал , з якого він був запущений в тому, закритий. Запустивши його у фоновому режимі, спочатку створюється підшалл, і команда працює у фоновому режимі, повертаючи вас у підказку.

У сценаріях негайний ефект є більш-менш однаковим, але <command>його починає ваш сценарій, і сценарій буде продовжуватися, не чекаючи <command>початку, відправки виводу або завершення.


Я теж не впевнений у тому, що робить виконавець. Я маю на увазі… Я розумію, що це має робити, але я бачу лише незначну різницю між тим, script.sh &чи робиш exec script.sh &. В обох випадках команда виконується в дочірньому процесі, вона не замінює процес виклику, див.: Paste.alacon.org/44474 (занадто довго, щоб копіювати її тут у коментарі…). Що я роблю неправильно?
Стефан

2

Ви не можете порівнювати nohupїх exec. Коли ви запускаєте виконуваний файл nohup, процес не загине при виході (ssh сесія); зазвичай nohupвикористовується niceдля запуску процесів з нижчим пріоритетом. HUPСигнал, за угодою, то , як термінал попереджає залежні процеси виходу з системи

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.