Я знаю, что, nohup
будучи бинарным, его можно получить из любой оболочки. Но exec
встроенный, вероятно, существует в каждой оболочке.
Есть ли причина отдавать предпочтение одному из них другому?
Что лучше, рыба или велосипед? 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 &
exec firefox
оболочка больше не работает: она была заменена наfirefox
. Вы можете думатьexec
как о сочетании выхода из программы и запуска новой, но с сохранением идентификатора процесса. Терминал продолжает работать , потому что ничего не сказал это остановить. При последующем выходе из Firefoxfirefox
процесс завершается. Терминал замечает, что его дочерний процесс завершился, и поэтому он выходит по очереди.exec &
=> выполняет процесс как фоновый процесс, поэтому вы можете продолжать использовать тот же терминал для других заданий.nohup
=> избегает всех SIGHUP (сигнал завершения) и продолжает выполнение, даже если ваш терминал закрыт.exec
процесс умирает, когдаSIGHUP
получено, ноnohup
процесс продолжается.источник
exec
заменяет запущенный процесс, но этого не происходит, когда вы используете&
в качестве фона команду exec'd. Ни в bash, ни в zsh.exec smth &
же, как это(exec smth) &
, не так ли?(exec smth) &
. Но я не ожидал бы, что это будет то же самое - я ожидаю, что это будет синтаксическая ошибка, как вы можете выполнить процесс (заменив себя), а затем выполнить фоновый процесс exec'd? Ты больше не для этого.Встроенная команда
exec <command>
оболочки заменяет оболочку<command>
: новый процесс не создается, новый PID не создается. После завершения<command>
обычно ваш терминал закроется. Запустив его в фоновом режиме, сначала создается подоболочка, которая затем аналогичным образом немедленно заменяется на<command>
.Команда
nohup <command>
будет выполняться,<command>
но будет зависеть от зависаний (kill -s 1), поэтому она не будет прервана, когда оболочка, с которой был запущен терминал, закрыта. Запустив его в фоновом режиме, сначала создается подоболочка, а команда запускается в фоновом режиме, возвращая вас к приглашению.В сценариях непосредственный эффект более или менее одинаков, хотя
<command>
он запускается вашим сценарием, и сценарий будет продолжаться, не дожидаясь<command>
запуска, отправки вывода или завершения.источник
script.sh &
илиexec script.sh &
. В обоих случаях команда выполняется в дочернем процессе, она не заменяет вызывающий процесс, см .: paste.alacon.org/44474 (слишком долго, чтобы скопировать его здесь в комментарии…). Что я делаю неправильно?Вы не можете сравнить
nohup
сexec
. Когда вы запускаете исполняемый файл с помощьюnohup
, процесс не будет завершен при выходе из системы (сессия ssh); обычноnohup
используетсяnice
для запуска процессов с более низким приоритетом. ПоHUP
соглашению, терминал предупреждает зависимые процессы выхода из системы.источник