Czy programy uruchamiane z sesji ssh zależą od połączenia?


29

Czy program uruchamiany z sesji ssh zależy od połączenia z klientem? Na przykład, gdy połączenie jest naprawdę wolne. Czy więc aktywnie czeka, aż rzeczy zostaną wydrukowane na ekranie?

A jeśli zależy to od połączenia, czy dzieje się tak również na przykład z ekranem lub byobu ? Ponieważ dzięki tym programom nadal działają, nawet po odłączeniu od hosta.


Uwaga: znalazłem tylko te powiązane pytania:


1
Pamiętaj, że jeśli połączenie zostanie utracone, program będzie kontynuował działanie do czasu przekroczenia limitu czasu sesji (chyba że utknie w operacji drukowania), ale jeśli sesja się zakończy, program zostanie zakończony z wdziękiem.
Sebb

Odpowiedzi:


26

Dane wyjściowe programów są buforowane, więc jeśli połączenie jest wolne, program zostanie zatrzymany, jeśli bufor się zapełni.

Jeśli używasz screen, ma również bufor, którego używa do próby wyświetlenia w połączonej sesji. Ale program podłączony do sesji ekranowej nie zostanie zatrzymany, jeśli nie będzie w staniescreen wystarczająco szybko zaktualizować zdalnego terminalu. Podobnie jak w przypadku utraty połączenia, program kontynuuje wypełnianie screensbufora, aż do jego przepełnienia (wypychanie najstarszych informacji). To, co widzisz (i które możesz przewinąć), zależy od tego, co jest (nadal) w tym buforze. screenskutecznie oddziela Twój program od terminala (i powolnego połączenia SSH).


9

Połączenie SSH może przedwcześnie zakończyć połączenie, jeśli bazowe połączenie TCP odbierze pakiet z flagą RST . Może się to zdarzyć, jeśli jedna strona wyśle ​​pakiet (który może być okresową sondą podtrzymującą SSH), ale nie otrzyma potwierdzenia TCP w rozsądnym czasie lub jeśli router zdecyduje, że połączenie było zbyt długo bezczynne, lub jeśli ISP jest po prostu zły.

W modelu terminala uniksowego, gdy połączenie terminala jest przerywane , sterownik terminala wysyła sygnał HUP do powłoki, którego zakończenie powoduje również wysłanie SIGHUP do procesów działających w powłoce.

Z FAQ programisty Unixa , pozycja 1.15:

SIGHUPjest sygnałem, który zgodnie z konwencją oznacza, że ​​linia terminalu się rozłączyła. Nie ma to nic wspólnego z procesami nadrzędnymi i zwykle jest generowane przez sterownik tty (i dostarczany do grupy procesów pierwszego planu).

Jednak w ramach systemu zarządzania sesjami SIGHUPwysyłane są dokładnie w przypadku śmierci procesu:

  • Gdy proces, który umiera, jest liderem sesji sesji podłączonej do urządzenia końcowego, SIGHUPjest wysyłany do wszystkich procesów w grupie procesów pierwszego planu tego urządzenia końcowego.

  • Gdy śmierć procesu powoduje, że grupa proces, by stać się sierotą, i jeden lub więcej procesów w osieroconej grupy są zatrzymane , a następnie SIGHUPi SIGCONTsą wysyłane do wszystkich członków grupy osieroconych. (Osierocona grupa procesów to taka, w której żaden proces w grupie nie ma elementu nadrzędnego, który jest częścią tej samej sesji, ale nie tej samej grupy procesów).

Obsługi domyślny sygnał SIGHUP jest zakończenie procesu:

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

Można jednak uniknąć zakończenia procesu.

  • Możesz wstawić moduł obsługi sygnału, który ignoruje SIGHUP. Aby to zrobić jako użytkownik, zawiń polecenie nohup. Na przykład:

    nohup make all &
    
  • Możesz powiedzieć powłoce, aby oddzieliła od niej proces potomny. Na przykład Bash ma disownwbudowane polecenie:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Wówczas SIGHUP nie będzie propagowany do dziecka (które nie jest już dzieckiem).

  • Niektóre programy, zwłaszcza demony , automatycznie wykorzystują powyższe mechanizmy: program może zainstalować alternatywną procedurę obsługi SIGHUP (za pomocą sigaction(2)) lub może dołączyć do nowej sesji ( setsid(2)).
  • Możesz uruchomić screenlub tmux, który przydziela pseudo-TTY, aby uruchomić sesję z powłoką, która nie odbiera SIGHUP, gdy połączenie SSH umrze. SIGHUP nie jest przekazywany z sesji SSH do sesji screen / tmux.

Nawiasem mówiąc, alternatywnym sposobem radzenia sobie z niewiarygodnymi połączeniami SSH jest użycie protokołu Mosh . Mosh działa na UDP, więc nie ma połączenia TCP, które mogłoby zostać zresetowane.



1

Tak, program działający na SSH będzie zależał od tego, gdzie jego wyjście pójdzie. Jeśli połączenie jest wolne, dane wyjściowe muszą być gdzieś buforowane, a bufory nie mogą być nieskończone, więc program musi blokować, jeśli są wypełnione.

Zauważ, że wyjście niekoniecznie musi przejść do terminala: rozważ uruchomienie czegoś takiego

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

Spowoduje to skopiowanie pliku. Aby to zadziałało, szybkość wyjściowa cat musi zgadzać się z szybkością połączenia: powinno być oczywiste, że utrata części wyjścia ze środka byłaby nie do przyjęcia.

Ekran zmieni sytuację, ponieważ będzie działał jak terminal i zapisze to, co powinno być pokazane „w oknie terminala” (plus przewijanie). Nie musi pamiętać wszystkich danych wyjściowych programu, tylko części pasujące do „okna” i przewijania. Domyślnie ekran będzie czekał na wolne połączenie (blokowanie programu), ale można go skonfigurować tak, aby wykrywał zablokowane połączenie, ustawiając „nonblock on”.

Ze strony podręcznika:

nonblock [on | off | numsecs]

Powiedz ekranowi, jak postępować z interfejsami użytkownika (ekranami), które przestają akceptować dane wyjściowe. Może się to zdarzyć, jeśli użytkownik naciśnie ^ S lub połączenie TCP / modem zostanie przerwane, ale nie zostanie zawieszone. Jeśli funkcja nonblock jest wyłączona (jest to ustawienie domyślne), ekran czeka na ponowne uruchomienie wyświetlacza, aby zaakceptować wyjście. Jeśli funkcja nonblock jest włączona, ekran czeka na przekroczenie limitu czasu (on jest traktowany jako 1s). Jeśli wyświetlacz nadal nie odbiera znaków, ekran uzna, że ​​jest „zablokowany” i przestanie wysyłać do niego znaki. Jeśli w pewnym momencie ponownie zacznie akceptować znaki, ekran odblokuje wyświetlacz i ponownie wyświetli zaktualizowaną zawartość okna.

Rozłączenie różni się od wolnego połączenia. Zwykły SSH nie może odzyskać go automatycznie, więc twój program otrzyma POWIĘKSZENIE. Z drugiej strony ekran wykryje rozłączenie, odłączy się i wróci do lokalnego buforowania, dopóki ekran nie zostanie ponownie podłączony. Będzie to nie blokuje program.

(Ustawienie nonblock 1w twoim .screenrcjest ważne, jeśli uruchamiasz coś takiego jak irssi, które będzie stale wytwarzało dane wyjściowe, ale nadal musi rozmawiać z siecią w tym samym czasie. Blokowanie prowadziłoby do odłączenia się od IRC, co jest bardzo denerwujące ...)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.