Отключение от сеанса SSH убивает ваши программы?


89

Так, скажем , я разъединен от SSH-сессии после того, как я начал rsyncили cpили любую другую команду , которая может быть долго работает. Продолжает ли эта команда выполняться до тех пор, пока она не будет завершена после того, как я отключусь, или она просто будет убита?

Всегда удивлялся этому.


Я просто хочу добавить к тому, что было сказано выше, что, если вы оказались в ситуации, когда вам нужно поместить уже запущенный процесс screen, попробуйте reptyr .
грустный чувак

Это убьет ваши программы. Очень раздражает, если вы обновляете версию ОС, скажем, с Ubuntu 16.04 до 17.10 через SSH
kurdtpage

Ответы:


118

Изменить на 2016 год:

Эти вопросы предшествуют разгрому systemd v230 . Начиная с systemd v230, новым значением по умолчанию является уничтожение всех дочерних элементов завершающего сеанса входа в систему, независимо от того, какие исторически действительные меры предосторожности были приняты для предотвращения этого. Поведение может быть изменено путем установки KillUserProcesses=noв /etc/systemd/logind.confили обойти с помощью Systemd конкретных механизмов для запуска демона в пользовательском пространстве. Эти механизмы выходят за рамки этого вопроса.

Приведенный ниже текст описывает, как вещи обычно работали в пространстве разработки UNIX дольше, чем существовал Linux.


Их убьют, но не обязательно сразу. Это зависит от того, сколько времени демон SSH решит, что ваше соединение разорвано. Далее следует более длинное объяснение, которое поможет вам понять, как это на самом деле работает.

Когда вы вошли в систему, демон SSH выделил для вас псевдотерминал и подключил его к настроенной оболочке входа вашего пользователя. Это называется управляющим терминалом. Каждая программа, которую вы обычно запускаете в этот момент, независимо от того, сколько слоев раковин в глубине, в конечном итоге будет прослеживать свою родословную до этой оболочки. Вы можете наблюдать это с помощью pstreeкоманды.

Когда процесс демона SSH, связанный с вашим соединением, решает, что ваше соединение разорвано, он отправляет сигнал зависания ( SIGHUP) в оболочку входа. Это уведомляет оболочку о том, что вы исчезли, и что она должна начать очистку после себя. То, что происходит в этот момент, относится к конкретной оболочке (поищите на странице документации «HUP»), но по большей части она начнет отправлять SIGHUPвыполняющиеся задания, связанные с ней, прежде чем завершится. Каждый из этих процессов, в свою очередь, будет делать все, что настроено для получения этого сигнала. Обычно это означает прекращение. Если на этих работах есть свои собственные работы, сигнал часто будет передаваться вместе.

Процессы, которые переживают зависание управляющего терминала, - это те, которые либо не связывают себя с наличием терминала (процессы демона, которые вы запустили внутри него), либо те, которые были вызваны с помощью префиксной nohupкоманды. (т.е. «не кладите трубку»). Демоны по-разному интерпретируют сигнал HUP; поскольку они не имеют управляющего терминала и не принимают автоматически сигнал HUP, вместо этого он перенаправляется в качестве ручного запроса от администратора для перезагрузки конфигурации. По иронии судьбы это означает, что большинство администраторов не изучают использование этого сигнала для не-демонов "зависанием" намного, намного позже. Вот почему вы читаете это!

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


Мне было предложено уточнить, сколько времени требуется демону SSH, чтобы решить, что ваше соединение разорвано. Это поведение, характерное для каждой реализации демона SSH, но вы можете рассчитывать на то, что все они прекратят работу, когда любая из сторон сбрасывает TCP-соединение. Это произойдет быстро, если сервер попытается выполнить запись в сокет, а пакеты TCP не будут подтверждены, или медленно, если ничего не будет предпринято для записи в PTY.

В этом конкретном контексте наиболее вероятными причинами записи являются:

  • Процесс (обычно на переднем плане), пытающийся записать в PTY на стороне сервера. (Server-> клиент)
  • Пользователь пытается записать в PTY на стороне клиента. (Клиент-> сервер)
  • Keepalive любого рода. Обычно они не включены по умолчанию ни клиентом, ни сервером, и обычно существует два варианта: уровень приложения и основанный на TCP (т.е. SO_KEEPALIVE). Keepalive равносильно тому, что сервер или клиент отправляют пакеты на другую сторону нечасто, даже если в противном случае не было бы причины для записи в сокет. Хотя это обычно предназначено для обхода брандмауэров, которые слишком быстро блокируют время ожидания соединения, у него есть дополнительный побочный эффект, когда отправитель замечает, что другая сторона не отвечает так быстро.

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

Если одна из сторон решила, что сокет мертв, эффекты обычно бывают немедленными: процесс sshd отправит HUPи завершит работу самостоятельно (как описано ранее), или клиент уведомит пользователя об обнаруженной проблеме. Стоит отметить, что только то, что одна сторона думает, что другая мертва, не означает, что другая сторона была уведомлена об этом. Потерянная сторона соединения, как правило, будет оставаться открытой до тех пор, пока она не попытается выполнить запись и тайм-аут или не получит сброс TCP с другой стороны. (если подключение было доступно в то время) Очистка, описанная в этом ответе, происходит только после того, как сервер заметил.


3
Я бы также добавил команду 'dtach' в этот список - это своего рода противоположность screen / tmux в том, что он позволяет подключать несколько терминалов к одному сеансу, а также отлично подходит для продления сеанса, хотя это не так. предоставить любые средства воспроизведения недавней истории.
пушистый

dtachURL здесь: dtach.sourceforge.net
ОДС

2
отличное объяснение. Я уже чувствую себя более уверенно!
Fregas

3
Кроме того, хотя это технически не является частью вашего ответа, вот интересная мелочь: вы можете использовать в kill -HUPкачестве пользователя root, чтобы заставить чей-либо терминал зависать. Вы не должны делать это без уважительной причины. Я получаю большую часть своего пробега, когда пользователи оставляют оболочки запущенными во время обслуживания, и мне нужно размонтировать файловую систему, которую их оболочка держит открытой. Если пользователь подключен, но находится в режиме ожидания, отправьте сигнал его процессу sshd. В противном случае, если он работает внутри терминального мультиплексора, отправьте его в оболочку, которую вы хотите остановить. Только повесьте оболочку, удерживая вас от работы!
Андрей B

@AndrewB, не могли бы вы рассказать, как "процесс демона SSH ... решает, что ваше соединение разорвано"? И как я могу узнать, думает ли демон SSH / знает, что (какое) соединение разорвано или нет?
Сяо Пэн - ZenUML.com

22

Как уже упоминалось, после того, как вы отключитесь от ssh, все, что работает в нем, исчезнет.

Как уже упоминали @Michael Hampton и другие, вы можете использовать такие инструменты, как tmuxили screenдля отключения / повторного подключения к терминалам без потери их содержимого (то есть дочерних процессов).

Кроме того, вы можете поместить процесс в фоновый режим, используя амперсанд, &а затем использовать команду, disownчтобы отсоединить их от текущей оболочки.

# start a command
% sleep 5000 &
[1] 3820

# check it
% jobs
[1]+  Running                 sleep 5000 &

# disown everything
% disown -a

# check it again (gone from shell)
% jobs
%

# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml      3820 23791  0 00:16 pts/1    00:00:00 sleep 5000
%

Можно ли заново присоединить сеанс терминала к disownпроцессу ed?
Фальшивое имя

4
Да. Смотрите эту U & L вопрос для деталей: unix.stackexchange.com/questions/4034/...
ОДС

13

Нет, любые программы, все еще подключенные к терминалу и не помещенные в фоновый режим с чем-то вроде nohup, будут убиты.

Вот почему существуют виртуальные терминальные решения, такие как tmuxи старые, screenкоторые создают сеансы, которые продолжают работать, даже если вы отключены, и к которым вы можете подключиться позже.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.