В чем разница между nohup и амперсандом

243

Оба nohup myprocess.out &или myprocess.out &установите myprocess.out для запуска в фоновом режиме. После того, как я выключил терминал, процесс все еще работает. Какая разница между ними?

Yarkee
источник
какую оболочку вы используете? поведение меняется в зависимости от снарядов
shx2
1
Баш. И теперь я знаю почему, согласно ответу @nemo.
Ярки
@ Ярки, если ответ соответствует вашей проблеме, отметьте вопрос как принятый (флажок под голосами ответа), чтобы он не болтался как оставшийся без ответа. Вы должны сделать это для всех ваших вопросов :)
Немо
1
shutdownследует избегать как термин с особым смыслом Linux., и должен быть заменен на exit.
Патрицио Бертони,

Ответы:

317

nohupловит сигнал зависания (см. man 7 signal), а амперсанд - нет (за исключением того, что оболочка сконфигурирована таким образом или не отправляет SIGHUPвообще).

Обычно при запуске команды с использованием &и выходе из оболочки после этого оболочка завершает подкоманду сигналом зависания ( kill -SIGHUP <pid>). Это может быть предотвращено с помощью nohup, так как он ловит сигнал и игнорирует его, так что он никогда не достигает фактического приложения.

Если вы используете bash, вы можете использовать команду, shopt | grep huponчтобы узнать, отправляет ли ваша оболочка SIGHUP своим дочерним процессам или нет. Если он выключен, процессы не будут прекращены, как вам кажется. Более подробную информацию о том, как bash завершает приложения, можно найти здесь .

Есть случаи, когда nohupне работает, например, когда процесс, который вы запускаете, повторно подключает SIGHUPсигнал, как это имеет место здесь .

Немо
источник
Возможно, стоит отметить, что &подкоманда просто не получает некоторые сигналы (например, SIGINT). nohupсущественно добавляет SIGHUPв список сигналов, которые не распространяются.
Studgeek
46

myprocess.out &будет запускать процесс в фоновом режиме, используя подоболочку. Если текущая оболочка прервана (скажем, из-за выхода из системы), все подоболочки также прекратятся, так что фоновый процесс также будет прерван. Команда nohup игнорирует HUPсигнал и, следовательно, даже если текущая оболочка прервана, подоболочка myprocess.outбудет продолжать работать в фоновом режиме. Другое отличие состоит в том, что &одно только не перенаправляет stdout / stderr, поэтому, если есть какие-либо выходные данные или ошибки, они отображаются на терминале. nohup, с другой стороны, перенаправляет stdout / stderr в nohup.outили $HOME/nohup.out.

amit_g
источник
6
Я бегу myprocess.out &и выхожу из снаряда. Тем не менее, когда я использую ps aux | grep myprocess.outв другой оболочке, я все еще могу найти "myprocess.out". Это значит, что процесс еще не запущен, а не прекращается.
Ярки
1
@amit_g При уничтожении родительской оболочки с kill -9помощью SIGHUP не будет, поскольку для этого потребуется родительская оболочка для обработки SIGKILL, чего не может быть.
Немо
2
Проверьте магазин | grep hupon как упомянуто в другом ответе.
amit_g
31

Большую часть времени мы подключаемся к удаленному серверу, используя ssh. Если вы запустите скрипт оболочки и выйдете из системы, процесс будет остановлен. Nohup помогает продолжить выполнение сценария в фоновом режиме даже после выхода из оболочки.

Nohup command name &
eg: nohup sh script.sh &

Nohup ловит сигналы HUP. Nohup не помещает работу автоматически в фоновом режиме. Мы должны сказать это явно, используя &

missgeorge
источник
Спасибо. Не ожидал вашего ответа, но тот факт, что он здесь, великолепен. Он отвечает на вопрос, который я не задавал: D
Вайбхав Каушал
26

Использование амперсанда (&) запустит команду в дочернем процессе (дочернем по отношению к текущему сеансу bash). Однако при выходе из сеанса все дочерние процессы будут уничтожены.

использование nohup + ampersand (&) сделает то же самое, за исключением того, что когда сеанс завершится, родительский процесс дочернего процесса будет изменен на «1», который является процессом «init», таким образом сохраняя дочерний процесс от уничтожения.

Мишель
источник
7

Поправьте меня если я ошибаюсь

  nohup myprocess.out &

nohup ловит сигнал зависания, что означает, что он отправит процесс, когда терминал закрыт.

 myprocess.out &

Процесс может быть запущен, но будет остановлен после закрытия терминала.

nohup myprocess.out

Процесс может запустить даже закрытый терминал, но вы можете остановить процесс, нажав ctrl+ zв терминале. Crt+ zне работает, если &существует.

Джон Джо
источник
2

Команда nohup - это утилита маскирования сигналов, которая перехватывает сигнал зависания. Где как амперсанд не ловит сигналы зависания. Оболочка прекратит выполнение подкоманды с сигналом зависания при запуске команды с использованием & и выходе из оболочки. Это можно предотвратить с помощью nohup, так как он ловит сигнал. Команда Nohup принимает сигнал зависания, который может быть отправлен ядром процессу и блокирует их. Команда Nohup полезна в тех случаях, когда пользователь хочет начать длительный выход из приложения или закрыть окно, в котором был запущен процесс. Любое из этих действий обычно заставляет ядро ​​зависнуть в приложении, но оболочка nohup позволит продолжить процесс. Использование амперсанда запустит команду в дочернем процессе и этом дочернем элементе текущего сеанса bash. Когда вы выходите из сессии, все дочерние процессы этого процесса будут убиты. Амперсанд относится к управлению заданиями для активной оболочки. Это полезно для запуска процесса в сеансе в фоновом режиме.

Сантош
источник
0

Есть много случаев, когда небольшие различия между средами могут вас укусить. Это тот, в который я недавно столкнулся. В чем разница между этими двумя командами?

1 ~ $ nohup myprocess.out &
2 ~ $ myprocess.out &

Ответ такой же, как обычно - зависит.

nohup ловит сигнал зависания, а амперсанд - нет.

Что такое сигнал зависания?

SIGHUP - обнаружение зависания на управляющем терминале или прекращение управляющего процесса (значение: 1).

Обычно при запуске команды с использованием & и последующем выходе из оболочки оболочка завершает подкоманду сигналом зависания (например, kill -SIGHUP $ PID). Это можно предотвратить с помощью nohup, так как он ловит сигнал и игнорирует его, так что он никогда не достигает реального приложения.

Хорошо, но, как в этом случае, всегда есть «но». Нет никакой разницы между этими методами запуска, когда оболочка настроена таким образом, что она вообще не отправляет SIGHUP.

Если вы используете bash, вы можете использовать команду, указанную ниже, чтобы узнать, отправляет ли ваша оболочка SIGHUP своим дочерним процессам:

~ $ shopt | grep hupon

И более того - бывают случаи, когда nohup не работает. Например, когда процесс, который вы запускаете, повторно подключает сигнал NOHUP (это делается внутри, на уровне кода приложения).

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

В одной среде Linux все работало гладко, во второй приложение закрывалось сразу после выхода из второго сценария (обнаружение этого случая, конечно, заняло у меня гораздо больше времени, чем вы могли подумать: stuck_out_tongue :).

После добавления nohup в качестве метода запуска во второй сценарий приложение продолжает работать, даже если сценарии завершаются, и это поведение стало согласованным в обеих средах.

Девендер Гоял
источник