Разница между nohup, disout и &
В чем разница между
$ nohup foo
и
$ foo &
и
$ foo &
$ disown
3 ответа
Давайте сначала посмотрим, что произойдет, если программа запускается из интерактивной оболочки (подключенной к терминалу) без &
(и без какого-либо перенаправления). Итак, допустим, вы только что набрали foo
:
- Создается процесс
foo
. - Процесс наследует stdin, stdout и stderr из оболочки. Поэтому он также подключается к одному и тому же терминалу.
- Если оболочка получает
SIGHUP
, она также отправляет процессуSIGHUP
(который обычно приводит к завершению процесса). - В противном случае оболочка ждет (блокируется), пока процесс не завершится.
Теперь посмотрим, что произойдет, если вы поместите процесс в фоновом режиме, то есть введите foo &
:
- Создается процесс
foo
. - Процесс наследует stdout /stderr из оболочки (так что он все еще записывается в терминал).
- Процесс в принципе также наследует stdin, но как только он пытается читать из stdin, он останавливается.
- Он помещается в список фоновых заданий, которыми управляет оболочка, что особенно важно:
- Он указан в
jobs
и может быть доступен с помощью%n
(гдеn
- номер задания). - Его можно преобразовать в задание переднего плана, используя
fg
, и в этом случае он будет продолжаться, как если бы вы не использовали&
на нем (и если он был остановлен из-за попытки чтения со стандартного ввода, теперь он может перейти к чтению с терминала). - Если оболочка получила
SIGHUP
, она также отправляет процессуSIGHUP
. В зависимости от оболочки и, возможно, от параметров, установленных для оболочки, при завершении оболочки она также отправит процессуSIGHUP
.
- Он указан в
Теперь disown
удаляет задание из списка заданий оболочки, поэтому все вышеперечисленные подпункты больше не применяются (в том числе процесс отправки SIGHUP
оболочкой ). Однако обратите внимание, что к терминалу подключается еще , поэтому, если терминал разрушен (что может произойти, если оно было pty, как те, которые создаются с помощью xterm
или ssh
, и управляющая программа завершается, закрывая xterm или завершая SSH соединение), программа выйдет из строя, как только она попытается прочитать стандартный ввод или записать на стандартный вывод.
С другой стороны, nohup
- это эффективно отделить процесс от терминала:
- Он закрывает стандартный ввод (программа not может читать любой ввод, даже если он запущен на переднем плане. Он не останавливается, но получит код ошибки или
EOF
). - Он перенаправляет стандартный вывод и стандартную ошибку в файл
nohup.out
, поэтому программа не сработает для записи на стандартный вывод, если терминал выходит из строя, поэтому независимо от того, что процесс записи не потерян. - Это предотвращает получение процесса
SIGHUP
(таким образом, имя).
Обратите внимание, что nohup
выполняет not удаление процесса из управления заданиями оболочки, а также не помещает его в фоновом режиме (но с переднего плана nohup
более или менее бесполезен, вы обычно помещаете его в фоновом режиме с помощью &
). Например, в отличие от disown
, оболочка все равно сообщит вам о завершении задания nohup (если оболочка не завершится раньше, конечно).
Итак, суммируем:
-
&
помещает задание в фоновом режиме, то есть блокирует попытку чтения ввода и делает оболочку не дожидаясь ее завершения. -
disown
удаляет этот процесс из управления заданиями оболочки, но он все равно оставляет его подключенным к терминалу. Один из результатов заключается в том, что оболочка не отправит егоSIGHUP
. Очевидно, что он может применяться только к фоновым заданиям, потому что вы не можете ввести его, когда выполняется задание переднего плана. -
nohup
отключает процесс от терминала, перенаправляет его вывод наnohup.out
и защищает его отSIGHUP
. Одним из эффектов (именованием) является то, что процесс не получит никакого отправленногоSIGHUP
. Он полностью независим от управления заданиями и в принципе может использоваться для работы на переднем плане (хотя это не очень полезно).
Использование &
заставляет программу работать в фоновом режиме, поэтому вы получите новое приглашение оболочки вместо блокировки, пока программа не закончится. nohup
и disown
в значительной степени не связаны; они подавляют сигналы SIGHUP (зависания), поэтому программа автоматически не убивается, когда управляющий терминал закрыт. nohup
делает это, когда начинается работа. Если вы не выполняете nohup
задание при его запуске, вы можете использовать disown
для изменения выполняемого задания; без аргументов он изменяет текущее задание, которое было только что запомнено
Вот мой опыт, пытающийся запустить soffice в фоновом режиме, следуя команде без конца (например, tail
). В этом примере я буду использовать sleep 100
.
& амп;
#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
I см. soffice журналы /, нажав Ctrl - C soffice останавливается
nohup .. &
#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
I не вижу soffice logs /, нажимая Ctrl - C soffice останавливается
& амп; открестился
#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100
I см. soffice журналы /, нажав Ctrl - C soffice останавливается
setsid .. &
#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
I см. soffice журналы /, нажав Ctrl - C soffice НЕ ОСТАНОВИТЬ
Чтобы сэкономить место: nohup setsid ..
: не показывает logs /soffice НЕ ОСТАНЕТСЯ на Ctrl - C nohup
с помощью & disown
в конце: не отображает журналы / soffice останавливается на Ctrl - C