Чи залежать програми, які працюють із сеансу ssh, залежно від з'єднання?


29

Чи залежить програма, що запускається з сеансу ssh, від підключення до клієнта? Наприклад, коли з'єднання дійсно повільне. Тож чи активно чекає, коли речі надрукуються на екрані?

І якщо це все-таки залежить від з'єднання, це також трапляється, наприклад, з екраном або byobu ? Оскільки за допомогою цих програм, вони продовжують працювати навіть після відключення від хоста.


Примітка. Я знайшов лише такі пов'язані питання:


1
Зауважте, що якщо ваше з’єднання втрачено, програма продовжуватиме працювати до тих пір, коли очікується час сеансу (за винятком випадків, коли вона застрягла в операції друку), але якщо ваш сеанс закінчиться, програма буде граціозно припинена.
Себ

Відповіді:


26

Вихід програм буферизований, тому, якщо з'єднання повільне, програма буде припинена, якщо буфер заповнюється.

Якщо ви використовуєте screen, у нього є також буфер, який він використовує для спроби та відображення підключеного сеансу. Але програма, підключена до екранного сеансу, не буде зупинена, якщо screenне вдасться оновити віддалений термінал досить швидко. Як і коли втрачається з'єднання, програма продовжує заповнювати screensбуфер, поки він не переповнюється (витісняючи найдавнішу інформацію). Те, що ви бачите (і може прокрутити назад), залежить від того, що знаходиться в цьому буфері. screenефективно відключає вашу програму від вашого терміналу (і вашого повільного SSH-з'єднання).


9

З'єднання SSH може відмовитися передчасно, якщо базовий TCP-з'єднання отримає пакет із прапором RST . Це може статися, якщо одна сторона надсилає пакет (який може бути періодичним зондом SSH-кепаліву), але не отримує підтвердження TCP в розумний проміжок часу, або якщо маршрутизатор вирішить, що з'єднання простоювало, або якщо Інтернет-провайдер просто злий.

У моделі терміналу Unix, коли термінальне з'єднання відхилено, драйвер терміналу передає сигнал оболонки HUP в оболонку, припинення якої також викликає відправлення SIGHUP на процеси, що працюють в оболонці.

З пункту 1.15 про програміст 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
    

    CtrlZ

    bg
    disown %1
    

    Тоді SIGHUP не поширюватиметься на дитину (яка вже не є дитиною).

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

До речі, альтернативним способом поводження з ненадійними з'єднаннями SSH є використання протоколу Mosh . Mosh працює над UDP, тому не існує з'єднання TCP, яке ризикує отримати скидання.


Подальше читання: Різниця між nohup, disown і & .
200_успіх

1

Так, програма, що працює над SSH, залежатиме від її результату, кудись піде. Якщо з'єднання повільне, вихід повинен бути десь буферним, а буфери не можуть бути нескінченними, тому програма повинна блокуватися, якщо вони заповнені.

Зауважте, що висновок може не обов’язково переходити до терміналу: розгляньте запуск чогось подібного

ssh user@somewhere "cat file.txt" > file.txt

Це фактично скопіює файл. Щоб це працювало, вихідний коефіцієнт кішки повинен відповідати рівню з'єднання: повинно бути очевидним, що втрачати частину виходу з середини було б неприпустимо.

Екран змінить ситуацію в тому, що він діє як термінал і збереже те, що має бути показано "у вікні терміналу" (плюс прокрутка). Не потрібно пам’ятати про все, що виводить ваша програма, лише ті частини, які підходять до «вікна» та прокрутки. За замовчуванням екран буде чекати повільного з'єднання (блокує програму), але його можна налаштувати на виявлення застрялого з'єднання, встановивши "неблокувати".

На чоловіковій сторінці:

розблокувати [on | off | numsecs]

Розкажіть екрану, як поводитися з користувацькими інтерфейсами (дисплеями), які перестають приймати вихід. Це може статися, якщо користувач натискає ^ S або з'єднання TCP / модем перерветься, але жодне з’єднання не отримано. Якщо вимкнено блокування (це за замовчуванням) екран очікує, поки дисплей перезапуститься, щоб прийняти вихід. Якщо розблокування увімкнено, екран чекає, поки не буде досягнуто тайм-аут (включене вважається 1s). Якщо дисплей все ще не отримує символів, екран вважатиме його "заблокованим" і перестане надсилати символи на нього. Якщо через деякий час він перезапустить для прийому символів, екран розблокує дисплей і повторно відобразить оновлений вміст вікна.

Відключення відрізняється від повільного з'єднання. Звичайний SSH не може відновитись з нього автоматично, тому ваша програма отримає SIGHUP. З іншого боку, екран виявить відключення, від'єднається та повернеться до локального буферизації, поки екран не буде встановлений повторно. Це буде не заблокує запущену програму.

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

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