Зберігання процесу Linux після запуску


142

Я підключаюся до машини Linux через SSH, і я намагаюся запустити важкий скрипт bash, який робить операції з файловою системою. Очікується, що він працюватиме годинами, але я не можу залишити сеанс SSH відкритим через проблеми з підключенням до Інтернету.

Я сумніваюся, що запуск сценарію з фоновим оператором, ampersand ( &), зробить трюк, тому що я спробував це і пізніше виявив, що процес не завершився. Як я можу вийти з системи та тримати процес?

Відповіді:


135

Найкращий спосіб - запустити процес у термінальному мультиплексорі. Крім того, ви можете змусити процес не приймати сигнал HUP.


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

Усі процеси, запущені з віртуального терміналу, будуть продовжувати працювати з цим віртуальним терміналом. Після повторного підключення до сервера ви зможете підключитися до віртуального терміналу, і все буде так, ніби нічого не сталося, крім часу, який минув.

Два популярні термінальні мультиплексори - це екран та tmux .

Екран має круту криву навчання. Ось хороший підручник із схемами, що пояснюють концепцію: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


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

Два простих способи зробити це є nohupі disown.

Для отримання додаткової інформації про те, як nohupі як disownчитати, прочитайте це запитання та відповідь: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

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


3
Мені подобається ця відповідь, оскільки вона пропонує рішення як для інтерактивних, так і неінтерактивних ситуацій. В інтерактивному випадку screenдає вам набагато більше варіантів, але якщо ви використовуєте, authorized_keysщоб дозволити людям дистанційно запускати скрипт ssh, цей nohupваріант є хорошим простим способом для скрипту запускати процеси, які тривають довше, ніж sshсеанс, який використовується для їх запуску. .
Марк Бут

1
@rahmanisback - Пам’ятайте, що ви можете будь-коли змінити прийняту відповідь. Тільки тому, що поки відповідь Еріки проголосовано найбільш високо, це не означає, що це найкраща відповідь для вас, адже, якщо ваша прийнята відповідь, цілком можна заохотити більше людей проголосувати її за добру відповідь.
Марк Бут

3
* кашель * tmuxisbetter * кашель *
катастрофа

3
tmux > екран. Спробуйте, ви ніколи не повернетесь.
h0tw1r3

1
@TheLQ - byobu - це екран GNU. Ви все ще використовуєте екран, лише із налаштованим .screenrc.
EEAA

92

Існує кілька способів зробити це, але один з них, який я вважаю найбільш корисним, - це використовувати GNU Screen .

Після того, як ви вступите, запустіть screen. Це запустить іншу оболонку, що працює в екрані. Виконайте свою команду, потім зробіть Ctrl- a d.

Це "відключить" вас від екранного сеансу. У цей момент ви можете вийти або зробити все, що завгодно.

Коли ви хочете повторно підключитися до екранного сеансу, просто запустіть screen -RDіз запиту оболонки (як той самий користувач, який створив сеанс).


6
Екран має цілу купу команд, починаючи з Ctrl-a. Якщо ви дізнаєтесь лише одну зайву, почніть з "Ctrl-a?". Тоді ви не захочете вивчати "Ctrl-a c" та "Ctrl-a n"
olafure

@olafure +1, спасибі Схоже, Екран буде моїм основним інструментальним набором.
doc_id

tmux > екран. Спробуйте, ви ніколи не повернетесь.
h0tw1r3

+1 для tmux. Я відмовився від екрану 5 тижнів тому.
Брайан Хант

73

У bash, disownключове слово цілком підходить до цього. Спочатку запустіть процес у фоновому режимі (або використовуйте &, або ^Zпотім введіть bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

Ввівши, jobsви побачите, що процес все ще належить оболонці:

$ jobs
[1]+  Running  wget

Якби ви в цей момент вийшли з системи, фонове завдання також загине. Однак якщо ви запустите disown, bash від'єднує завдання та дозволяє йому продовжувати виконувати:

$ disown

Ви можете підтвердити це:

$ jobs
$ logout

Ви навіть можете комбінувати &і disownв тому ж рядку, як:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

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


1
Це дуже гарна відповідь, 1+. Єдиною перевагою для nohup або Screen буде незалежність bash, і його можна використовувати з іншою оболонкою. Але я буду дотримуватися вашого підходу щоразу, коли використовую баш.
doc_id

Так - це специфічно для bash, оскільки bash - єдина оболонка, яку я коли-небудь використовував. Цікаво, чи підтримують інші снаряди щось подібне (тобто запуск у фоновому режимі без нохупу) - було б фантастично, якби хтось міг розмістити інші відповіді на інші снаряди.
Джеремі Віссер

1
дивіться мою відповідь, що показує, як це зробити з будь-яким sh-lookalike
w00t

1
+1 через можливість прийняти рішення пізніше. Якраз у цей момент у мене була потреба в цьому. працювали як рекламується
code_monk

37

Це зробить інструмент nohup, доступний у більшості ящиків Linux.


1
Це, безумовно, найпростіша відповідь. Будь-який вихід із автоматично спрямовується на nohup.out і може бути вивчений пізніше.
Джуліан

3
nohup взагалі не вимагає zsh.
Аарон Браун

nohup - це правильна відповідь, вона не має жодної повірки.
Kinjal Dixit

2
nohup не знайдено на набагато більше машинах, ніж на екрані, тому ви повинні знати, як ним користуватися.
Зенон

27

Щоб бути ретельним, я зазначу tmux , який має таку ж основну ідею, як екран:

tmux призначений як сучасна альтернатива BSD з такими програмами, як GNU screen. Основні характеристики включають:

  • Потужний, послідовний, добре задокументований та легко командний інтерфейс.
  • Вікно може бути розділене горизонтально і вертикально на панелі.
  • Панелі можна вільно переміщувати та змінювати, або розміщувати за попередньо встановленими макетами.
  • Підтримка UTF-8 та 256-кольорових терміналів.
  • Скопіюйте та вставте декілька буферів.
  • Інтерактивні меню для вибору вікон, сесій або клієнтів.
  • Змініть поточне вікно, шукаючи текст у цілі.
  • Блокування клем вручну або після таймауту.
  • Чиста, легко розширена база даних, що має ліцензію на BSD, під час активного розвитку.

Однак пошук у Google приблизно нескінченно простіше.


2
Використання "gnu screen"в якості пошукового запиту працює досить добре.
gnur

4
+1000 за tmux!
mbq

11

Екран є зайвим для простого запуску процесів під час виходу.

Спробуйте dtach :

dtach - це програма, написана на C, що імітує функцію від'єднання екрану, яка дозволяє виконувати програму в середовищі, захищеному від керуючого терміналу. Наприклад, на програму під контролем dtach не впливатиме відключення терміналу з якихось причин.

dtach був написаний тому, що екран недостатньо відповідав моїм потребам; Мені не потрібні додаткові функції екрана, такі як підтримка декількох терміналів або підтримка емуляції терміналу. Екран також був занадто великим, об'ємним і мав вихідний код, який було важко зрозуміти.

екран також заважав моєму використанню повноекранних програм, таких як emacs та ircII, через його надмірну інтерпретацію потоку між програмою та доданими терміналами. dtach не має рівня термінальної емуляції терміналу і передає вихідний потік програми в додані термінали. Єдина обробка вводу, яку виконує dtach, - це сканування символу від'єднання (який сигналізує dtach про відхилення від програми) та обробка ключа призупинення (який повідомляє dtach тимчасово призупинити себе, не впливаючи на запущену програму), і обидва вони можуть обидва бути відключеним за бажанням.

На відміну від екрану, dtach має мінімальні функції та надзвичайно крихітний. Це дозволяє dtach легше перевіряти на предмет помилок та отворів у безпеці та робить його доступним у середовищах, де простір обмежений, наприклад, на рятувальних дисках.


Дякую. Я прийшов сюди просто для публікації про dtach теж. Зараз це моя річ для відключення терміналу; екран робить WAY занадто багато і заважає вводити смішні міри. Факт екрану потребує власної термінальної шапки - дуже непокоїть.
пухнастий

9

Ось спосіб демонізувати будь-який процес оболонки, не потрібні зовнішні програми:

( while sleep 5; do date; done ) <&- >output.txt &

Коли ви закриєте сеанс, робота продовжуватиметься, як свідчить файл output.txt (який має буферизацію, щоб не було нуля). Не забудьте вбити свою роботу після тестування.

Отже, все, що вам потрібно зробити, це закрити stdin і вирішити цю роботу. Щоб бути справді хорошим, спочатку, cd /щоб ви не трималися на горі.

Це працює навіть у простих ш під Solaris.


Цікаво. То виникли деякі помітні питання. Я можу бачити, що ви встановлюєте STDIN нічого, -оператор? У чому різниця між < /dev/nullі &-? Я думаю, що STDIN (та інші STDOUT та STDERR) у випадку STDIN можуть бути призначені або файлом < file, або потоком <& stream. Чи було б те саме, що використовується < /dev/nullу вашому прикладі вище? А чи -звертається вище оператор до нуля як потоку?
doc_id

Коли ви робите x <& -, це закриває дескриптор файлу x. У цьому випадку немає x, що робить bash за замовчуванням 1, тобто стандартним входом. Якщо ви використовуєте </ dev / null, ви не закриваєте stdin, ви просто надаєте порожній файл програмі як вхід.
w00t

1
І якщо чесно, я не знаю, чому це визнає те, що ви працюєте :-) Хоча це і працює, але ми використовуємо це у виробництві. Я виявив це, коли возився, сподіваючись, що зможу демонструвати процес в оболонці, не потребуючи нічого особливого - тому я почав із закриття stdin, і цього було досить. Мені слід прочитати деякі джерела оболонок, але я припускаю, що якщо ви закриєте stdin і перетворите цей процес, він також від'єднує процес.
w00t

2
Я думаю, що причина полягає в тому, що SIGHUP (фактичний сигнал, який змушує дитину відмовитися, коли шкаралупа гине) спрацьовує, коли батьківський процес закриває ручку stdin своєї дитини. Однак якщо stdin починається як нульовий, а не закривається після факту, батько не може запустити SIGHUP. Хоча приємна знахідка - ніколи про це не подумав би.
Джеремі Віссер

@JeremyVisser, що звучить справді правдоподібно!
w00t

7

atКоманда може бути корисною для такого роду ситуації. Наприклад, введіть:

at now

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

Замість цього nowви можете вказати час, необов'язково, з датою чи тимчасовим виразом now + 15 minutes. Дивіться man atдокладнішу інформацію.


7

byobuна Ubuntu - приємний передній екран. Натискаючи Ctrl- ?ви отримуєте список усіх комбінацій клавіш. Він додає рядок стану, який може бути корисним для перегляду завантаження процесора, дискового простору тощо. Загалом, це забезпечує досвід, який я б назвав термінальним VNC-з'єднанням.

nohup дозволяє запускати роботу у фоновому режимі, а його вихід направляється на файл журналу, який завжди може бути перенаправлений на / dev / null, якщо цього не потрібно.

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