Запуск программ из сеанса ssh зависит от соединения?

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

И если это зависит от соединения, это также происходит с экраном или byobu , например? Так как с этими программами продолжают работать даже после отключения от хоста.


Примечание. Я нашел только эти связанные вопросы:

28 голосов | спросил agold 13 Maypm16 2016, 15:16:07

3 ответа


25

Вывод программ буферизуется, поэтому, если соединение медленное, программа будет остановлена, если буфер заполнится.

Если вы используете screen, у него есть буфер, который он использует, чтобы попытаться отобразить подключенный сеанс. Но программа, связанная в сеансе экрана, будет не остановлена, если screen не сможет достаточно быстро обновить удаленный терминал. Так же, как когда соединение потеряно, программа продолжает заполнять буфер screens до тех пор, пока он не переполнится (выталкивает самую старую информацию). То, что вы видите, приходит (и может прокручиваться назад) зависит от того, что (все еще) в этом буфере. screen эффективно отключает вашу программу от вашего терминала (и ваше медленное соединение SSH).

ответил Anthon 13 Maypm16 2016, 15:22:39
9

Соединение SSH может умереть преждевременно, если базовое TCP-соединение получает пакет с RST . Это может произойти, если одна сторона отправляет пакет (который может быть периодическим зондированием SSH), но не получает подтверждение TCP за разумное время или если маршрутизатор решает, что соединение слишком долгое время, или если провайдер просто злой.

В терминальной модели Unix, когда соединение терминала отключено, драйвер терминала отправляет сигнал HUP в оболочку , завершение которого также вызывает отправку SIGHUP в процессы, запущенные в оболочке.

Из FAQ для программистов Unix , пункт 1.15:

  

SIGHUP - это сигнал, который, по соглашению, означает, что «конечная линия получила   повесить ". Он не имеет ничего общего с родительскими процессами и обычно   сгенерированный драйвером tty (и переданный на передний план   группа).

     

Однако, как часть системы управления сеансом, есть точно   два случая, когда SIGHUP отправляется при смерти процесса:

     
  • Когда процесс, который умирает, является лидером сеанса сеанса   то есть    прикрепленный к терминальному устройству, SIGHUP отправляется всем процессам в    группа процесса переднего плана этого терминального устройства.

  •   
  • Когда смерть процесса приводит к тому, что группа процессов становится   сироты,    и один или несколько процессов в оси сиротской группы остановлены , тогда    SIGHUP и SIGCONT отправляются всем членам осиротевшей группы.    (Сиротная группа процессов - это группа, в которой ни один процесс в группе не имеет    родитель, который является частью одного сеанса, но не тот же процесс    группы.)

  •   

обработчик сигнала по умолчанию для SIGHUP заключается в завершении процесса:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

Однако можно избежать завершения процесса.

  • Вы можете вставить обработчик сигнала, который игнорирует SIGHUP. Чтобы сделать это как пользователь, оберните команду в nohup. Например:

    nohup make all &
    
  • Вы можете сказать оболочке отделить дочерний процесс от него. Например, у Bash есть disown встроенная команда:

    make all
    
         

    CTRL Z

    bg
    disown %1
    

    Затем SIGHUP не будет распространяться на дочерний элемент (который уже не является дочерним).

  • Некоторые программы, в частности демоны , будут автоматически использовать механизмы: программа может установить альтернативный SIGHUP обработчик (используя sigaction(2) ), или он может выбрать присоединение к новому сеансу ( setsid(2) ) литий>
  • Вы можете запустить screen или tmux, который выделяет псевдо-TTY для запуска сеанса с оболочкой, которая не получает SIGHUP, когда соединение SSH умирает. SIGHUP не передается из сеанса SSH в сеанс экрана /tmux.

Кстати, альтернативный способ справиться с ненадежными SSH-соединениями - вместо этого использовать Mosh . Мош работает над UDP, поэтому нет TCP-соединения, которое может быть сброшено.

ответил 200_success 13 Maypm16 2016, 21:46:07
1

Да, программа, работающая через SSH, будет зависеть от того, что ее выход будет куда-то. Если соединение происходит медленно, выход должен быть где-то буферизирован, а буферы не могут быть бесконечными, поэтому программа должна блокировать, если они заполнены.

Обратите внимание, что вывод может не обязательно перейти к терминалу: запустите что-то вроде

ssh [email protected] "cat file.txt" > file.txt

Это приведет к копированию файла. Чтобы это работало, скорость вывода cat должна соответствовать скорости соединения: должно быть очевидно, что потеря части результата с середины будет неприемлемой.

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

На странице man:

  

nonblock [on | off | numsecs]

     

Расскажите, как работать с пользовательскими интерфейсами (дисплеями), которые прекращаются   для приема вывода. Это может произойти, если пользователь нажимает ^ S или TCP /модем   соединение обрезается, но не происходит зависания. Если неблокировать выключено   (это по умолчанию), пока он не перезапустится   принять вывод. Если неблокировано, экран ждет, пока   тайм-аут достигнут (на него обрабатывается 1 с). Если дисплей по-прежнему   не получает символов, экран будет считать его «заблокированным» и   прекратите отправку символов на него. Если в какой-то момент он перезапускается, чтобы принять   символы, экран разблокирует дисплей и повторно отобразит обновленный   содержимое окна.

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

(Установка nonblock 1 в вашем .screenrc важно, если вы запускаете что-то вроде irssi, которое будет непрерывно выпускать выход, но все равно должно говорить с сетью в одно и то же время. Блокировка приведет к отключению от IRC, что крайне раздражает ...)

ответил ilkkachu 14 Maypm16 2016, 20:53:11

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132