Різниця між nohup, disown і &


579

Які відмінності між ними

$ nohup foo

і

$ foo &

і

$ foo & 
$ disown

50
Зачекайте, ви можете відмовитися, не вказуючи PID? Чудово!
ripper234

34
Є також те, foo &!що повинно дорівнювати відмови від нього з самого початку.
користувач4514

26
Bash не підтримує & !.
Йонас Конгслунд

20
foo & disownнегайно відмовитися.
ctrl-alt-delor

9
Я хотів би побачити згадку про те setsid, і як це стосується disownіnohup
YoungFrog

Відповіді:


558

Давайте спочатку розглянемо, що відбувається, якщо програма запускається з інтерактивної оболонки (підключена до терміналу) без &(і без перенаправлення). Тож припустимо, що ви щойно набрали foo:

  • Створений процес, що працює foo.
  • Процес успадковує stdin, stdout та stderr від оболонки. Тому він також підключений до того ж терміналу.
  • Якщо оболонка отримує a SIGHUP, вона також надсилає a SIGHUPв процес (що зазвичай призводить до припинення процесу).
  • В іншому випадку оболонка чекає (блокується), поки процес не припиниться.

Тепер давайте подивимося, що станеться, якщо ви поставите процес на другий план, тобто введіть foo &:

  • Створений процес, що працює foo.
  • Процес успадковує stdout / stderr від оболонки (тому він все ще пише в термінал).
  • Процес в принципі також успадковує stdin, але як тільки він намагається прочитати з stdin, він зупиняється.
  • Він вноситься до списку фонових завдань, якими керує оболонка, а це особливо:
    • Він перерахований з ним jobsі доступ до нього можна отримати %n(де nномер роботи).
    • Це можна перетворити на переднє завдання, використовуючи fg, і в цьому випадку воно продовжується так, як ніби ви його не використовували &(і якщо його зупинили через спробу читання зі стандартного вводу, тепер він може перейти до читання з терміналу).
    • Якщо оболонка отримала a SIGHUP, вона також надсилає a SIGHUPв процес. Залежно від оболонки та, можливо, від параметрів, встановлених для оболонки, при завершенні оболонки вона також надсилатиме a SIGHUPв процес.

Тепер disownвилучає завдання зі списку завдань оболонки, тому всі вищевказані підпункти більше не застосовуються (включаючи процес, який передає SIGHUPоболонка). Однак зауважте, що він все-таки підключений до терміналу, тому якщо термінал знищений (що може статися, якщо це був pty, як, наприклад, створений xtermабо ssh, і програма контролю припиняється, закриваючи xterm або припиняючи з'єднання SSH ) , програма вийде з ладу, як тільки вона спробує прочитати зі стандартного вводу або записати на стандартний вихід.

З nohupіншого боку, це ефективно відокремити процес від терміналу:

  • Він закриває стандартний вхід (програма не зможе прочитати жоден вхід, навіть якщо він запускається на передньому плані. Він не зупиняється, але отримає код помилки або EOF).
  • Він перенаправляє стандартний вихід і стандартну помилку до файлу nohup.out, тому програма не зможе записати на стандартний вихід, якщо термінал вийде з ладу, тому все, що пише процес, не буде втрачено.
  • Це перешкоджає процесу отримання SIGHUP(таким чином імені).

Зауважте, що nohupце не видаляє процес з управління завданнями оболонки, а також не ставить його на другий план (але, оскільки nohupзавдання переднього плану є більш-менш марними, ви, як правило, викладаєте його на другий план за допомогою &). Наприклад, на відміну від з disown, оболонка все одно повідомить вам, коли робота нохупа завершена (якщо, звичайно, оболонка не припиняється раніше).

Отже, підсумовуючи:

  • & ставить завдання на другий план, тобто блокує спробу читання введення та змушує оболонку не чекати її завершення.
  • disownвидаляє процес з управління роботою оболонки, але він все ще залишає його підключеним до терміналу. Одним із результатів є те, що оболонка не надсилатиме його SIGHUP. Очевидно, він може бути застосований лише до фонових завдань, оскільки ви не можете ввести його, коли виконується завдання переднього плану.
  • nohupвідключає процес від терміналу, перенаправляє його вихід nohup.outі захищає його SIGHUP. Один із ефектів (іменний) полягає в тому, що процес не отримає жодного надісланого SIGHUP. Він повністю незалежний від контролю за роботою, і в принципі може використовуватися і для переднього плану (хоча це не дуже корисно).

8
+1 Дякую Що відбувається, коли потім використовувати disown, nohup та & разом?
Тім

15
Якщо ви використовуєте всі три разом, процес працює у фоновому режимі, видаляється з управління роботою оболонки і ефективно відключається від терміналу.
celtschk


1
в чому різниця між disown %1і disown -h %1? Друга буде зберігатися як звичайна робота (але ігнорує сигнал HUP) до виходу терміналу?
schemacs

4
Може бути , варто в тому числі (foo&)подоболочек
jiggunjer

169

Використання &змушує програму запускатися у фоновому режимі, тож ви отримаєте нове запит оболонки замість блокування, поки програма не закінчиться. nohupі disownзначною мірою не пов'язані між собою; вони пригнічують сигнали SIGHUP (зависання), тому програма не забивається автоматично, коли контрольний термінал закритий. nohupробить це, коли робота починається вперше. Якщо ви не виконуєте nohupроботу, коли вона починається, ви можете disownзмінити запущену роботу; без жодних аргументів вона змінює поточну роботу, яка є тією, що була лише фоновою


10
Незначна різниця між nohup та disown: команда disown видалить її зі списку завдань; nohup не буде.
Шон Дж. Гофф

191
nohupі те і disownінше, можна сказати, пригнічують SIGHUP, але по-різному. nohupзмушує програму ігнорувати сигнал спочатку (програма може змінити це). nohupтакож намагається домовитись, щоб у програмі не було контрольного терміналу, щоб воно не надсилалося SIGHUPядром, коли термінал закритий. disownє чисто внутрішньою оболонкою; він змушує оболонку не надсилатись, SIGHUPколи вона закінчується.
Жиль

27
@Gilles, ваш коментар вартий самої відповіді.
lesmana

5
Лише уточнення щодо коментаря @ ShawnJ.Goff, що стосується disownвидалення роботи зі списку робочих місць. Якщо параметр не вказаний, він видаляє його зі списку завдань. Однак якщо вказати -hпараметр, кожен робочийспект не видаляється з таблиці. Натомість це робить його таким, що SIGHUPне надсилається до завдання, якщо оболонка отримує а SIGHUP.
такоту вівторок

4
Просто для уточнення, використання &не дає вам терміналу, воно відривається stdinвід процесу і змушує його працювати у фоновому режимі, але і те, stdoutі інше stderrвсе ще приєднане до поточного tty. Це означає, що ви можете отримати текст з різних програм, змішаних разом, що може бути дуже прикро, якщо ви робите gimp &і отримуєте безліч помилок GTK +, намагаючись використовувати цей tty для чогось іншого.
Френк

8

Ось мій досвід намагатися запустити soffice у фоновому режимі, слідуючи команді, що не закінчується (наприклад tail). Для цього прикладу я буду використовувати sleep 100.

&

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Я бачу журнали Soffice / натискаючи Ctrl- Csoffice зупиняється

nohup .. &

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Я не бачу журналів Soffice / натисканням Ctrl- Csoffice припиняється

& відхреститися

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

Я бачу журнали Soffice / натискаючи Ctrl- Csoffice зупиняється

setid .. &

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Я бачу журнали Soffice / натискаючи Ctrl- Csoffice НЕ СТОПУЄ

Щоб заощадити місце::
nohup setsid ..не показує журнали / софіт неCtrlC зупиняється на -
nohup з & disownв кінці: не показує журнали / зупинки софіту на Ctrl-C


2
Хоча я ціную зусилля згадати setid та показати те, що відбувається в конкретній ситуації, я хотів би побачити більш ґрунтовну відповідь. Зокрема, різниця та схожість кожного рішення, як видимих ​​(що відбувається при закритті оболонки або терміналу, куди йде вихід, ...), так і невидимих ​​(як це робиться під кришкою та їх наслідками). Прийнята відповідь є приємною базою для цього.
ЯнгФрог

1
@YoungFrog Я погоджусь на це!
Марінос Ан

Для мене зі nohup ⟨command⟩ & disownствореним процесом не зупиняється Ctrl+C.
k.stm

@ k.stm Ви пробували soffice? sofficeЗдається, команда має щось інше. Тому я розглядав можливість додавання сюди як правило виняток. наприклад, при використанні:, nohup .. &натискання Ctrl-cзвичайно не призводить до припинення команди, але при sofficeцьому відбувається. Я чекаю, поки хтось зробить на цьому крок і пояснить, чому це трапляється з суфіксом :)
Марінос Ан

@MarinosAn Так, я. Я побіг nohup soffice &і натиснув Ctrl+C. Нічого не сталося, як очікувалося.
k.stm
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.