Давайте спочатку розглянемо, що відбувається, якщо програма запускається з інтерактивної оболонки (підключена до терміналу) без &(і без перенаправлення). Тож припустимо, що ви щойно набрали 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. Він повністю незалежний від контролю за роботою, і в принципі може використовуватися і для переднього плану (хоча це не дуже корисно).