zaLinux.ru

5 способов сделать так, чтобы программа не останавливалась после отключения SSH


Если описать работу SSH (Secure Shell — безопасная оболочка) простыми словами, то её функция в том, что это простой способ подключиться к удалённому компьютеру от имени существующего на той системе пользователя с возможностью выполнять команды на ней. В первую очередь это относится к командам с интерфейсом командной строки, но также возможна передача и других видов трафика. В более технических терминах, когда мы подключаемся по ssh к другому пользователю на какой-либо системе и запускаем на той машине команды, то в действительности создаётся псевдо терминал и он подсоединяется к оболочке с входом (login shell) выполнившего вход пользователя.

Когда мы выходим (разлогиниваемся) из сессии, или сессия закрывается после таймаута из-за неактивности в течение определённого времени, то сигнал SIGHUP отправляется псевдо терминалу и все работы, которые были запущены в этом терминале, даже работы, которые имеют их родительские работы инициированные в псевдо терминале, также получают сигнал SIGHUP для принудительного закрытия.

Только работы, которые были настроены для игнорирования этого сигнала, переживают терминацию сессии. На системах Linux есть много способов сделать эти работы запущенными на удалённом сервере или любой машине даже после выхода пользователя и терминации сессии.

Основы о процессах в Linux

Нормальные процессы

Нормальные процессы это те, у которых продолжительность жизни ограничивается сеансом. Они запускаются во время сессии как процессы переднего плана и завершаются через определённое время или когда сессия прекращается из-за выхода пользователя. Эти процессы имеют своего владельца, которым является любой валидный пользователь системы, включая root.

Осиротевшие процессы

Осиротевшие процессы это те, которые изначально имели родительский, создавший их процесс, но после некоторого времени родительский процесс непреднамеренно завершил работу или остановился из-за ошибки, что сделало init родителем данного процесса. Такие процессы имеют init в качестве их непосредственного родителя, который ожидает от этих процессов остановки или завершения их работы.

Процессы демонов

Это процессы, которые намеренно сделаны осиротевшими. Процессы, которые намеренно оставлены работающими в системе, называются демонами или намеренно осиротевшими процессами. Обычно это процессы с длительным выполнением, которые после инициации были отсоединены от контролирующего терминала чтобы они могли работать в фоне, пока они не завершать их задачи или пока в них не возникнет ошибка. Родители таких процессов намеренно завершают свою работу, делая так, что дочерний процесс выполняется в фоне.

Техники для сохранения запущенной SSH сессии после отключения

Могут быть различные способы оставить ssh сессию запущенной после отключения, они описаны далее:

1. Использование команды screen для сохранения запущенных сессий SSH

screen — это текстовый менеджер окон для Linux, который позволяет пользователям управлять несколькими сессиями терминала одновременно, переключаться между сессиями, вести журнал действий в сессии для запущенных в screen сессий и даже возобновлять сессии в любой время по нашему желанию не беспокоясь о том, что произойдёт выход из сессии или терминал будет закрыт.

Сессии screen могут быть запущены и затем отсоединены от контролирующего терминала, что оставит их запущенными в фоне и затем их можно заново подсоединить в любое время и даже в любом месте (выполнив вход по SSH с другого компьютера). Всё что нужно, это запустить сессию в screen и когда вы хотите, отсоединить её от псевдо терминала (или контрольного терминала) и выйти из сессии. Когда нужно, вновь выполните вход по SSH и возобновите сессию.

После запуска команды screen, вы будете внутри новой сессии screen, в этой сессии вы можете создавать новые окна, перемещаться между окнами, блокировать окна и делать многое другое, что вы можете делать в обычном терминале:

screen

Теперь, когда сессия session запущена, можно запустить любую команду и сохранить сессию на случай отключения выполнив отсоединение сессии.

Отсоединение экрана screen

Когда вы хотите отключиться от удалённой сессии, но хотите созданную вами сессию сохранить живой, то вам просто нужно отсоединить screen от терминала, чтобы у него не осталось контролирующего терминала. После этого вы можете безопасно отключиться.

Для отсоединения screen от удалённого терминала просто нажмите Ctrl+a, а затем нажмите d и вы вернётесь в терминал, в котором увидите сообщение, что Screen отсоединён. Всё готово — можно выходить из сессии (например, отключиться от SSH), а запущенный в эту сессию процесс останется работать.

Возобновление отсоединённой сессии screen

Если вы хотите возобновить отсоединённую сессию screen, которую вы оставили перед тем как отключиться, просто снова повторно залогинтесь на удалённом терминале и наберите

screen -r

Предыдущая команда подходит если у вас только одна сессия screen.

Если открыто несколько сессий screen, то после опции -r нужно указать её индивидуальный идентификатор.


Следующая команда при нескольких запущенных сессиях выведет их список с идентификаторами:

screen -r

Для подключения к одной из них нужно ввести команду вида:

screen -r <pid.tty.host>

Чтобы узнать больше о программе screen и как её использовать смотрите по ссылке: «Как пользоваться screen для управления терминалами Linux и отсоединения процессов от терминала».

2. Использование Tmux (мультиплексора терминалов) чтобы программа работала после отключения от SSH

Tmux — это ещё одна программ, которая создана на замену screen. В ней имеется большинство возможностей screen, а также несколько дополнительных функций, которые делают её более мощной чем screen.

Она позволяет, кроме всех других опций, которые предлагает screen, разделение экрана терминала по горизонтали и вертикали, чтобы иметь сразу несколько консолей, позволяет изменять размер этих панелей, имеется мониторинг активности сессий, поддержка скриптов используя режим командной строки и т. д. Благодаря этим функциям tmux, он имеется практически во всех дистрибутивах Unix и даже был включён в базовую систему OpenBSD.

Запуск сессии Tmux

После подключения к удалённому хосту по SSH, наберите в командной строке:


tmux

Вы откроете новую сессию с новым окном — здесь вы можете делать всё что угодно как в обычном терминале.

После выполнения ваших операций в терминале, вы можете отсоединить эту сессию от контрольного терминала, чтобы она перешла в фон, и вы смогли безопасно отключиться от SSH.

Отсоединение сессии Tmux от терминала

В запущенной сессии tmux вы можете набрать:

tmux detach


Либо вы можете использовать сочетание клавиш, нажмите Ctrl+b, а затем нажмите d. После этого ваша текущая сессия будет отсоединена и вы вернётесь в ваш терминал, который вы можете безопасно закрыть (отключиться от SSH).

Возобновление фоновой сессии Tmux

Чтобы повторно открыть сессию, которую вы отсоединили и вернуть всё в то состояние, в котором находился терминал до того, как вы отключились от системы, просто повторно залогинтесь на удалённую машину и наберите

tmux attach

чтобы подсоединить закрытую сессию. Она вернётся, и запущенная в ней программа будет работать как прежде.

Чтобы узнать больше о tmux, о его возможностях и других командах и комбинациях клавиш, смотрите статью «Как пользоваться tmux для создания нескольких терминалов внутри одной консоли».

3. Использование команды nohup чтобы программа не закрывалась после отключения от SSH

Если вы не особо знакомы со screen или tmux вы можете использовать nohup и отправить вашу долго выполняющуюся команду в фон, чтобы вы могли продолжать работать в терминале, пока команда будет выполняться в фоне. Также при переводе команды в фон вы можете отключиться от удалённой системы, не опасаясь, что запущенная программа будет остановлена.

С командой nohup мы говорим процессу игнорировать сигнал SIGHUP который отправляется сессией ssh при её завершении, это делает команду устойчивой даже после выхода из сессии. При отключении от сессии, команда отсоединяется от контролирующего терминала и продолжает работать в фоне как процесс демона.

Выполнение команды в фоне используя nohup

Это простой сценарий в котором во время сессии SSH мы запустили команду find для поиска файлов в фоне используя nohup. При отправке работы в фон в приглашение терминала возвращается JOBID и PID процесса.

nohup find / -type f $gt; files_in_system.out 2>1 &

Возобновление сессии для просмотра всё ещё работающей задачи

Когда вы повторно залогинитесь, вы можете проверить статус команды, вернув её на передней план:

fg %JOBID

%JOBID — это цифра в квадратных скобках, например [1], тогда для перевода её на передней план введите:

fg 1

Если программа уже завершила свою работу, то вы увидите что-то вроде:

bash: fg: 1: нет такого задания

По умолчанию программа также сохраняет свой вывод в файл nohup.out — в противном случае, после завершения программы уже не получится вернуть данные, которые вывела программа.

При переводе на передний план программа не показывает свой вывод — в этом состоянии её можно только остановить комбинацией CTRL+c.

Подробности о nohup смотрите в статье «Как закрыть терминал без убийства запущенной в нём команды».

4.Использование команды disown для сохранения запущенной сессии SSH

Другим элегантным способом позволить вашей команде или единичной задаче работать в фоне и оставаться активной даже после выхода из сессии является использование disown.

Disown удаляет работу из списка процессов работ системы, таким образом, процесс защищён от уничтожения во время отключения сеанса, поскольку он не получит SIGHUP от оболочки при выходе из системы.

Недостаток этого метода заключается в том, что его следует использовать только для заданий, которые не нуждаются в вводе из stdin (стандартного ввода) и не нуждаются в записи в stdout (стандартный вывод), если только вы не перенаправите ввод и вывод заданий, потому что, когда задание будет пытаться взаимодействовать со стандартным вводом или стандартным выводом, процесс остановится.

Выполнение команды с использованием disown в фоновом режиме

Ниже мы отправили команду ping в фоновый режим, чтобы она продолжала работать и была удалена из списка заданий. Как видно, задание было сначала приостановлено, после чего оно все ещё оставалось в списке заданий с идентификатором процесса: 4910.


ping zalinux.ru > pingout &
jobs -l
disown -h %1
ps -ef | grep ping

После этого работе был передан сигнал disown и она была удалена из списка работ, хотя ещё и запущена в фоне. Работа должна ещё быть запущена, когда вы повторно зайдёте на удалённый сервер:

ps -ef | grep ping

5. Использование команды setsid для поддержания сессии SSH в запущенном состоянии

Другой утилитой для достижения требуемого поведения является setsid. Nohup имеет недостаток в том смысле, что группа процессов процесса остаётся неизменной, поэтому процесс, запущенный с помощью nohup, уязвим для любого сигнала, отправляемого всей группе процессов (например, Ctrl+C).

С другой стороны, setsid распределяет новую группу процессов для выполняемого процесса, и, следовательно, созданный процесс полностью находится во вновь выделенной группе процессов и может безопасно выполняться, не опасаясь быть уничтоженным даже после выхода из сеанса.

Выполните любую команду, используя setsid

Здесь это показывает, что процесс 'sleep 10m' был отсоединён от управляющего терминала с момента его создания.

setsid sleep 10m
ps -ef | grep sleep

Теперь, когда вы повторно войдете в сеанс, вы все равно обнаружите, что этот процесс запущен.

ps -ef | grep [s]leep

Заключение

Если вы знаете другие способы, как сделать так, чтобы процесс продолжал работать даже после отключения от SSH (закрытия терминала), то обязательно укажите их в комментариях.


Рекомендуемые статьи:

2 Комментарии

  1. pol

    В конце первого пункта ссылка ведёт на на screen а на tmux.

    1. Alexey (Автор записи)

      Здравствуйте! Спасибо, что обратили внимание. Ошибку исправил.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *