Зачем использовать «nohup &» вместо «exec &»

67

Я знаю, что, nohupбудучи бинарным, его можно получить из любой оболочки. Но execвстроенный, вероятно, существует в каждой оболочке.

Есть ли причина отдавать предпочтение одному из них другому?

loxaxs
источник

Ответы:

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
велосипед> рыба
Крис Джейнс
6
Позволю себе не согласиться. Рыба, очевидно, является лучшим способом транспортировки, если она может быть реализована.
ПОЛЬЗОВАТЕЛЮ НУЖНА ПОМОЩЬ
6
@ THISUSERNEEDSHELP Но ведь велосипед - это лучшая еда?
Жиль "ТАК - перестань быть злым"
3
@GypsyCosmonaut После запуска exec firefoxоболочка больше не работает: она была заменена на firefox. Вы можете думать execкак о сочетании выхода из программы и запуска новой, но с сохранением идентификатора процесса. Терминал продолжает работать , потому что ничего не сказал это остановить. При последующем выходе из Firefox firefoxпроцесс завершается. Терминал замечает, что его дочерний процесс завершился, и поэтому он выходит по очереди.
Жиль "ТАК - перестань быть злым"
5
Дайте человеку рыбу, и вы накормите его на день. Дайте человеку велосипед, и он сможет покататься на нем в супермаркете и купить рыбу на всю жизнь.
Дэвид
18

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

nohup => избегает всех SIGHUP (сигнал завершения) и продолжает выполнение, даже если ваш терминал закрыт.

execпроцесс умирает, когда SIGHUPполучено, но nohupпроцесс продолжается.

Ани Менон
источник
1
Этот ответ представляется правильным. Как говорят другие ответы выше, обычно execзаменяет запущенный процесс, но этого не происходит, когда вы используете &в качестве фона команду exec'd. Ни в bash, ни в zsh.
Дэн Притц
@DanPritts Что значит с этим не бывает? Фоновый подпроцесс запускается и затем заменяется, так exec smth &же, как это (exec smth) &, не так ли?
17
1
Я имею в виду, что он не получает exec'd в том смысле, о котором вы обычно думаете (заменив текущую работающую оболочку) - он просто запускается как фоновый процесс. Я думаю, что это, вероятно, так же, как (exec smth) &. Но я не ожидал бы, что это будет то же самое - я ожидаю, что это будет синтаксическая ошибка, как вы можете выполнить процесс (заменив себя), а затем выполнить фоновый процесс exec'd? Ты больше не для этого.
Дэн
2

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

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

В сценариях непосредственный эффект более или менее одинаков, хотя <command>он запускается вашим сценарием, и сценарий будет продолжаться, не дожидаясь <command>запуска, отправки вывода или завершения.

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

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

user2660420
источник