Jak mogę ponownie połączyć się z sesją ssh po zerwaniu potoku?

28

Więc działałem apt-get upgradena serwerze, kiedy router uznał, że minęło zbyt wiele czasu, odkąd ostatnio mnie zdenerwował: porzucił wszystkie połączenia. Morał tej historii jest screenczęste korzystanie z routera typu bum.

W każdym razie zalogowałem się ponownie i stwierdziłem w htopie, że proces nadal tam wisiał, wciąż czekając na aktualizację Y / n (na szczęście jeszcze go nie trafiłem). Czy jest jakiś sposób, aby ponownie dołączyć do sesji, która została przerwana? Skończyło się na tym, że zabiłem go, ponieważ nie było to w środku zarządzania pakietami, ale byłoby wspaniale wiedzieć na przyszłość.

ζ--
źródło
1
Dziwię się, że apt-getproces wciąż działał. Powinien był umrzeć wraz z całym łańcuchem procesu aż do SSH. Zauważyłem, że do-dist-upgradeautomatycznie rozpoczyna się w sesji screen/ byobu: może w niektórych okolicznościach apt-getto samo?
nfirvine

Odpowiedzi:

16

Odpowiedź na twoje właściwe pytanie brzmi: nie możesz . Myślę, że głównym problemem jest brak synchronizacji procedur uwierzytelniania. To po prostu tak nie działa.

Jak zauważyłeś, rozwiązaniem jest użycie screena , gdy jest to możliwe (przy okazji, tmux jest alternatywą dla screena ).

styczeń
źródło
1
Ale co jeśli masz ssh bez hasła? Czy możesz to zrobić?
Sridhar Sarnobat
1
byobujest ładnym, łatwiejszym w użyciu screentmux
frontendem
Sridhar-Samobol, uwierzytelnianie wciąż musi mieć miejsce. Dołączenie do uruchomionej sesji nie ma możliwości ponownego wykonania wstępnego uzgadniania, więc niezmienniki byłyby zepsute, gdybyśmy wprowadzili nową sesję do istniejącej. Odpowiedź: nie
kevr
9

Do uruchamiania długotrwałych procesów używam screen lub byobu, jeśli chcesz bardziej przyjazny interfejs.

Do ekranu możesz użyć:

screen [program] [args]

Spowoduje to uruchomienie [programu] i jego [argumentów] w sesji ekranowej . Po zakończeniu programu sesja jest automatycznie zamykana. Jeśli chcesz zachować sesję po uruchomieniu programu, po prostu uruchom screen bez żadnych argumentów, a wewnątrz sesji pojawi się nowy monit. CTRL + A + D odłącza terminal od bieżącej sesji.

Aby ponownie dołączyć do poprzedniej sesji:

screen -r

Jeśli otwarta jest tylko jedna sesja, zostanie ona ponownie podłączona natychmiast. Jeśli trwa wiele sesji, zostanie wyświetlone pytanie, do której chcesz dołączyć. Jeśli znasz nazwę sesji, możesz po prostu dodać ją jako argument do tego wiersza poleceń.

Byobu to niezła poprawa. Opiera się na ekranie , ale u dołu znajduje się pasek, który pokazuje wszystkie bieżące sesje jako karty i umożliwia łatwiejsze poruszanie się po nich. Możesz:

  • F2 rozpocznij nową sesję
  • F3 przejdź do następnej karty sesji po lewej stronie
  • F4 przejdź do następnej karty sesji po prawej stronie
  • F8 nadaje przyjazną nazwę bieżącej karcie sesji
  • F9 otwiera menu opcji
  • CTRL + A + D odłącza wszystkie sesje od terminala.

SŁOWA PORADY : unikaj pozostawiania sesji otwartej przy użyciu katalogu głównego użytkownika . Jeśli ktoś uzyska dostęp do twojego terminala (lokalnie lub zdalnie), może łatwo ponownie dołączyć do trwającej sesji i użyć twojego systemu jako root. W razie potrzeby najlepiej rozpocząć sesję przy użyciu zwykłego wiersza poleceń użytkownika i sudo w razie potrzeby.

JulioHM
źródło
1
Czy mogę zacytować OP: „Morał tej historii jest częste używanie ekranu ”. Najwyraźniej nie o to tutaj chodziło.
stycznia
Dzięki za odpis, ale styczeń był poprawny.
Użyj sudo screen <polecenie>, aby ustawić ekran jako root, który potrzebuje dostępu sudo, aby ponownie się z nim połączyć. O wiele lepsze niż normalne uruchamianie ekranu, a następnie przejście do rootowania w nim.
djsmiley2k - CoW
8

Chociaż nie możesz ponownie dołączyć się do uszkodzonej sesji SSH, możesz ponownie rozpoznać proces uruchomiony w SSH - funkcjonalnie równoważny z tym, czego chcesz.

Instrukcje

W twoim przypadku przejmiesz apt-getproces kontrolowany z nowej sesji SSH, screensesji itp. Moim ulubionym do tego jest reptyrpolecenie:

$ sudo apt-get install reptyr
$ ps ax | grep apt-get
10626 pts/8   R+     0:32 apt-get upgrade

Następnie z pid znalezionym dla twojego procesu:

$ sudo reptyr -T 10626

Lub jeśli to nie zadziała, spróbuj:

$ reptyr 10626

Po tym etapie wszystkie dane wprowadzane z klawiatury przechodzą do przejętego programu. Niestety nie zobaczysz starych danych wyjściowych sesji SSH, takich jak dane apt-getwyjściowe z prośbą o potwierdzenie.

Objaśnienia

Istnieje wiele innych narzędzi, które działają w zasadzie tak samo jak reptyr(tzn. Poprzez ptracezałącznik debugowania). Zapoznaj się z następującymi pytaniami i odpowiedziami:

W powyższych instrukcjach reptyr 10626używa ptracezałącznika debugowania, podczas gdy sudo reptyr -T 10626polecenie używa kradzieży TTY i jest preferowane ( szczegóły ).

Wreszcie powodem, dla którego nie można przejąć sesji SSH w ten sposób, jest to, że sshdproces nie jest kontrolowany przez terminal hosta, zamiast tego zapewnia niewolniczą część terminala - ptsurządzenie - podczas gdy kontrolująca go część master znajduje się na komputer kliencki, tutaj z przerwaną sesją SSH pomiędzy. Kiedy wymusza się przejęcie takiego sshdprocesu reptyr -s <pid>, klawiatura wpisuje się w ten proces, a nie w aktywny proces potomny. Więc „Ctrl + Z” po prostu to zabije sshd.

Tanius
źródło
1

Dlatego robiłem do-dist-upgradeprzez ssh z laptopa, który został zawieszony Broken pipe. Po powrocie do komputera widziałem, że nadal działają procesy związane z aktualizacją, w tym whiptailpytanie o dane wejściowe (który menedżer wyświetlania wybrać) i, odpowiednio, root SCREEN. Byłem w stanie to zrobić sudo su -i screen -rdołączyć do sesji, a oto, mam przed sobą okno dialogowe whiptail, które jest w stanie uzyskać wkład. Udało mi się bezproblemowo wznowić aktualizację.

Uwaga: była to aktualizacja z Ubuntu 14.04 do 16.04.

haelix
źródło