Що саме визначає, чи спрацьовує фонове завдання при виході з оболонки або вбивається?


12

Це питання прийшов досить на багато ( дуже багато ), але я знаходжу відповіді в цілому неповними. Загальне питання: "Чому мою роботу не вбивають, коли я виходжу / вбиваю ssh?", І ось що я знайшов. Перше питання: Наскільки загальною є така інформація? Наступне, здається, справедливо для сучасного Linux Linux Debian, але мені не вистачає деяких біт; а що потрібно знати іншим?

  1. Усі дочірні процеси, фонові чи не оболонки, відкриті через ssh-з'єднання, знищуються програмою SIGHUP, коли ssh-з'єднання закрито, лише якщо встановлено huponexitпараметр: запустіть, shopt huponexitщоб побачити, чи це правда.

  2. Якщо huponexitце правда, то ви можете використовувати nohupабо disownвідмежувати процес від оболонки, щоб він не загинув при виході. Або запускайте речі screen.

  3. Якщо huponexitзначення false, що є типовим для принаймні деяких Linux на цих днях, фонові завдання не будуть знищені при звичайному виході.

  4. Але навіть якщо huponexitце неправда, тоді, якщо ssh-з'єднання буде вбито , або перепаде (відрізняється від звичайного виходу), фонові процеси все одно загинуть. Цього можна уникнути disownабо, nohupяк у (2).

  5. Існує деяка різниця між (a) процесами, батьківським процесом яких є термінал, і (b) процесами, у яких stdin, stdout або stderr пов'язані з терміналом . Я не знаю, що відбувається з процесами, які є (а), а не (б), або навпаки.

Заключне питання: Як я можу уникнути поведінки (3)? Іншими словами, за замовчуванням у фонових процесах Debian запускаються весело самі після виходу, але не після вбиття ssh-з'єднання. Я хотів би, щоб те ж саме відбувалося з процесами, незалежно від того, нормально було закрито з'єднання чи вбито. Або це погана ідея?

Редагувати: Ще один важливий спосіб зберегти завдання вбивства, який працює (?) В будь-якому випадку - це запускати їх через екран . Але питання стосується більше розуміння того, коли вбиваються речі, а коли їх немає: іноді люди хочуть, щоб робочі місця були вбиті під час виходу, наприклад.

Більше потоків: - Роз'яснення сигналів (зітхання), завдань та керуючого терміналу - /server/117152/do-background-process-get-a-sighup-when-logging-off - Продовжити SSH фонове завдання / завдання при закритті SSH - Чи буде завдання, поставлене у фоновому режимі, продовжувати працювати після закриття сеансу SSH? - Запобігти вже запущений фоновий процес від зупинки після закриття клієнта SSH - Як я можу почати процес над SSH таким чином, що він буде продовжувати працювати після того, як я відключаю? - Неможливо тримати віддалену роботу в ОС X - Закрити з'єднання SSH

Відповіді:


1

Процес не "вбито за допомогою SIGHUP" - принаймні, не в суворому розумінні цього слова. Швидше за все, коли з'єднання припинено, процес управління терміналом (в даному випадку Bash) надсилається сигналом відключення *, який зазвичай скорочується "HUP signal", або просто SIGHUP.

Тепер, коли процес отримує сигнал, він може обробляти його будь-яким способом **. За замовчуванням для більшості сигналів (включаючи HUP) - негайно вийти. Однак програма може замість цього ігнорувати сигнал або навіть виконувати якусь функцію обробника сигналу.

Bash вибирає останній варіант. Його обробник сигналу HUP перевіряє, чи є правдою параметр «huponexit», і якщо так, то надсилає SIGHUP кожному своєму дочірньому процесу. Тільки після того, як його закінчено, Баш виходить.

Аналогічно, кожен дочірній процес може робити все, що завгодно, коли отримує сигнал: залиште його встановленим за замовчуванням (тобто померти негайно), проігноруйте його або запустіть обробник сигналу.

Nohup лише змінює дію за замовчуванням для дочірнього процесу на "ігнорування". Однак після запуску дочірнього процесу вільна зміна власної реакції на сигнал.

Я думаю, саме тому деякі програми вмирають, навіть якщо ви запускали їх з nohup:

  1. Nohup встановлює дію за замовчуванням "ігнорувати".
  2. Програмі потрібно зробити якесь очищення під час її виходу, тому вона встановлює обробник SIGHUP, випадково перезаписуючи прапор "ignore".
  3. Коли приходить SIGHUP, обробник запускається, очищаючи файли даних програми (або все, що потрібно зробити) і виходить із програми.
  4. Користувач не знає і не піклується про обробник чи очищення, і просто бачить, що програма вийшла, незважаючи на nohup.

Тут відбувається "відхилення". Процес, який відмовився Башем, ніколи не надсилає сигнал HUP, незалежно від опції huponexit. Тож навіть якщо програма налаштовує власний обробник сигналу, сигнал ніколи фактично не надсилається, тому обробник ніколи не працює. Однак зауважте, що якщо програма намагається відобразити якийсь текст користувачеві, який вийшов із системи, це призведе до помилки вводу / виводу, яка може все-таки вийти з програми.

* І, так, перед тим, як запитати, термін "відключення" залишається від днів комунікаційного набору UNIX.

** Більшість сигналів, все одно. Наприклад, SIGKILL завжди призводить до негайного припинення роботи програми, періоду.


2

Точки 1-4 є правильними. Я не знаю нічого про пункт 5. Що стосується остаточного пункту, точний додаток, екран , дозволить вам пустити всі процеси до їх природного кінця, незалежно від того, як ви припиняєте своє з'єднання. Екран знаходиться в репості.

Чоловічий опис екрана непростий для читання, але, серед іншого, він говорить:

Коли викликається екран, він створює єдине вікно з оболонкою в ньому (або вказаною командою), а потім виходить з вашого шляху, щоб ви могли використовувати програму як зазвичай. Потім у будь-який час можна створити нові (на весь екран) вікна з іншими програмами в них (включаючи більше оболонок), вбити існуючі вікна, переглянути список вікон, увімкнути та вимкнути вхід та вимкнути, скопіювати та вставити текст між вікнами, переглядати історію прокрутки, перемикатися між вікнами будь-яким способом і т. д. Усі вікна виконують свої програми повністю незалежно одне від одного. Програми продовжують працювати, коли їх вікно наразі не видно, і навіть коли весь сеанс екрана від'єднаний від терміналу користувача. Коли програма закінчується, екран (за замовчуванням) вбиває вікно, яке містило її. Якщо це вікно було на передньому плані, дисплей переходить у попереднє вікно; якщо нічого не залишилося, екран виходить.

Я виділив найважливішу частину: ви можете від'єднати вікно за допомогою команди Ctrl + a + d, а потім можете вбити / вийти з сеансу, і тепер відокремлене вікно продовжуватиме працювати, коли всередині програми все ще запущені. При підключенні назад, наприклад, ініціюючи новий сеанс ssh, командний екран -r відновить сеанс екрану, який був відключений раніше, при цьому всі видимість стандартної помилки / виводу буде добре видно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.