Ответы:
Что лучше, рыба или велосипед? 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
как о сочетании выхода из программы и запуска новой, но с сохранением идентификатора процесса. Терминал продолжает работать , потому что ничего не сказал это остановить. При последующем выходе из Firefox firefox
процесс завершается. Терминал замечает, что его дочерний процесс завершился, и поэтому он выходит по очереди.
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
соглашению, терминал предупреждает зависимые процессы выхода из системы.