Debian SSH - Zmiana rozmiaru terminalu nie rejestruje się w bash

11

Niedawno ponownie zainstalowaliśmy nasz serwer z powodu awarii dysku, a teraz mamy problem ze zmianą rozmiaru terminali. Zainstalowaliśmy Debian 6.0.6.

Objawy

Podczas zmiany rozmiaru terminala nie wydaje się, aby aplikacje oparte na ncurses (testowane: ytalk, irssi, screen, tmux, niektóre z przykładowych aplikacji ncurses) zmieniły rozmiar. Ekran zwykle jest pusty. Wymuszenie przerysowania w aplikacji spowoduje przerysowanie przy użyciu starego rozmiaru terminala.

Podczas zmiany rozmiaru okna po znaku zachęty (4.1.5 (1)) zmienne COLUMNS i LINES nigdy nie są aktualizowane.

Diagnostyka

Próbując złapać SIGWINCHA w bash, wydaje się, że nigdy nie jest odbierany. Zostało to przetestowane z:

trap 'touch /home/user/sigwinch' SIGWINCH
trap 'touch /home/user/sigusr1' SIGUSR1
kill -s SIGWINCH $$
kill -s SIGUSR1 $$

Które powinny były utworzyć oba pliki w moim katalogu domowym. To tylko stworzyło /home/user/sigusr1.

Próba kill -s SIGWINCH $$nie powoduje aktualizacji zmiennych $ COLUMNS / $ LINES.

Włączenie checkwinsize( shopt -s checkwinsize) spowoduje, że bash zaktualizuje $ COLUMNS / $ LINES po powrocie z dowolnej aplikacji (zgodnie z oczekiwaniami). Prowadzi to do następujących po zmianie rozmiaru terminala z checkwinsizewłączonym:

$ echo $COLUMNS ; ls > /dev/null ; echo $COLUMNS
72
107

Zmiana powłoki logowania na coś takiego jak tcsh i próba zmiany rozmiaru terminala działa zgodnie z oczekiwaniami, podobnie jak bash na innych testowanych przeze mnie urządzeniach.

Próbowałem usunąć plik .bashrc i nic nie dało. Ten problem występuje u kilku innych użytkowników z różnymi konfiguracjami bash zarówno w PuTTY, jak i pewnego rodzaju terminalu typu rxvt z Linux-a.

strace

Uruchomiłem strace na bashu i próbowałem zmienić rozmiar terminala, nic nie przeszło (pozostało zablokowane podczas readpołączenia natychmiast po wydrukowaniu monitu).

Nacisnąłem return na pustej linii i bash zrobił całą masę rzeczy. Wynik, który moim zdaniem jest istotny, to: ( pełna wersja )

1: rt_sigprocmask(SIG_SETMASK, [WINCH], NULL, 8) = 0
2: rt_sigaction(SIGWINCH, {0x80e2c20, [], SA_RESTART}, {0x809c310, [], 0}, 8) = 0
3: rt_sigprocmask(SIG_BLOCK, [INT], [WINCH], 8) = 0
4: write(2, "aa:~$ ", 6)                   = 6
5: rt_sigprocmask(SIG_SETMASK, [WINCH], NULL, 8) = 0
6: rt_sigprocmask(SIG_BLOCK, NULL, [WINCH], 8) = 0
7: read(0,

Który pokazuje bash, według mojego zrozumienia: (Mógłbym być strasznie niezrozumiały. Jestem tutaj daleko od mojego żywiołu.)

1: Disabling delivery of the SIGWINCH signal, when previously it was allowed.
2: Registering a handler for the SIGWINCH signal.
3: Masking some other combination of signals. As evidenced by line 5, this does not include SIGWINCH.
4: Printing the prompt.
5: Masking SIGWINCH, where previously nothing was blocked.
6: Masking the "union of null and SIGWINCH" which, to my understanding, would result in SIGWINCH being masked.
7: Waiting on input.

Ta sama strace wykonana na pudełku bez tych problemów (Ubuntu, bash 4.2.24 (1)) spowodowała:

1: rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
2: rt_sigaction(SIGWINCH, {0x49e320, [], SA_RESTORER|SA_RESTART, 0x7f7ef49f64c0}, {0x457880, [], SA_RESTORER, 0x7f7ef49f64c0}, 8) = 0
3: rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
4: write(2, "aaaaaaa:~$ ", 11)             = 11
5: rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
6: rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
7: read(0,

Pytanie

Co się do cholery dzieje i dlaczego moja łamana walka jest zepsuta? :(

Domyślam się, że prawdopodobnie jest gdzieś tylko opcja, która domyślnie spowodowała coś nieoczekiwanego, ale godziny w Google nic nie pokazały.

Każda pomoc i / lub wskazówki są bardzo mile widziane. To jest naprawdę frustrujące.

Dziękuję Ci.

NuclearDog
źródło
Nie jesteś pierwszy: lists.gnu.org/archive/html/bug-bash/2007-01/msg00084.html Jeśli exec bashręcznie (więc nie jest to już powłoka logowania), to nadal źle się zachowuje? Jeśli nie, to co z exec bash -l(więc jest to powłoka logowania)? Jeśli tak, to coś jest nie tak z twoimi skryptami logowania ( /etc/profile /etc/profile.d/ ~/.bash_profile ~/.profile), ale nawet nie wiem, co powiedzieć, żebyś szukał, co może powiedzieć powłoce, że nie SIGWINCH.
DerfK
Oba exec bashi exec bash -lwykazują takie same zachowanie. Przypuszczam, że to mała pociecha, że ​​nie jestem w tym sam. Jestem jednak całkowicie zdezorientowany, co by to spowodowało. Colo zainstalowało minimalną instalację ze świeżo pobranego obrazu Debiana. Będę musiał spróbować zainstalować lokalnie i sprawdzić, czy są jakieś problemy i (zakładając, że nie występują, ponieważ wydaje się, że tak się nie dzieje u innych osób), zacznij porównywać z działającym systemem.
NuclearDog,
Zrobiłem nową instalację na maszynie wirtualnej, wygenerowałem listę sum md5 wszystkich plików w / etc i / usr i porównałem z uszkodzonym systemem. Na pierwszy rzut oka nie widzę nic oczywiście złego. /etc/bash.bashrca wszystkie pliki /etc/profilei /etc/profile.dpozostają niezmienione od czystej instalacji. Pobrałem bash source ( apt-get source bash) i gram z różnymi argumentami, ./configureaby spróbować zawęzić problem przed kopaniem do źródła.
NuclearDog
Skompilowałem bash minus wszystkie łaty Debiana --disable-readline --enable-minimal-config --disable-job-control, uruchomiłem śledzenie, by zobaczyć, które to pliki open, zmieniłem nazwy wszystkich plików, a następnie zalogowałem się ponownie. Ten sam problem. Zupełnie zdecydowanie wykluczyłem wszelkie zmiany konfiguracji samego basha.
NuclearDog,
Powtórzyłem ten sam problem z kompilacją bash 3.2, 4.1 i 4.2 ze źródeł pobranych bezpośrednio z GNU. Nie mogłem skompilować 4.2 bez kontroli zadań i przy minimalnej konfiguracji z powodu niektórych błędów (zgłoszonych zespołowi bash). Biorąc pod uwagę, że dzieje się tak w przypadku kilku wersji bash, zaczynam wierzyć, że błąd może leżeć w jednej z bibliotek, od których zależy. Przechodząc do tego.
NuclearDog,

Odpowiedzi:

11

Coś mnie wkurzyło w wynikach strace. Mianowicie wydawało się, że kiedy zaczynało się bash, wydawało się, że już zamaskował SIGWINCH. Nie byłem pewien, nie rozumiałem połowy tego, co wypluł, ale na pewno warto było w tym momencie zbadać.

Uciekłem strace -o strace_file bash -lz powłoki tcsh, w której problem nie był obecny. bash nigdy nie maskował SIGWINCH. Kiedy ją maskował, to tylko dlatego, że próbował przywrócić poprzednią maskę. Skąd więc wzięła się początkowa maska?

Jeszcze trochę czasu w Google i świeżym umyśle. Znalazłem ten post, w którym wspomniałem, że aptitude może czasami powodować uruchomienie sshd z maskowaniem SIGWINCH i że zostanie on następnie odziedziczony przez wszystkie odrodzone procesy aż do powłoki.

Próbowałem ps axwwws(wszystkie, odłączone, szerokie wyjście, sygnały). Pokazało, że kilka spawnowanych procesów sshd ma SIGWINCH zamaskowany.

Proces serwera / nasłuchiwania (sam sshd) nie. Nie działały też procesy hostujące połączenia korzystające z tcsh. Ta część jest dla mnie myląca. Zgaduję (znowu, wiedząc bardzo mało na ten temat), że maska ​​sygnału jest szeroka dla grupy procesów czy coś takiego, tcsh resetuje ją przy starcie, i to również wpływa na ssh.

Tak więc, dla kaprysu, połączyłem się z tcsh (aby uzyskać czysty termin bez maski SIGWINCH), ponownie uruchomiłem ssh, zmieniłem moją powłokę z powrotem na bash ... I to zadziałało! Wszystko wróciło do normy!

O ile wiem, aptitude nie zostało uruchomione na tym polu, a ssh został ponownie uruchomiony kilka razy w celu zmiany konfiguracji. Gdzieś po drodze maska ​​się przedostała i zaraziła wszystko jak złą chorobę.

Aby rozpoznać ten sam problem, uruchom ps axwwws | grep sshdi wyszukaj procesy sshd z drugą długą kolumną ( BLOCKED) ma ustawiony 0x8000000. To jest SIGWINCH. Coś jak:

   0 26425 0000000000000000 0000000008000000 0000000000001000 0000000180004003 Ss   ?          0:00 sshd: aa [priv]
1000 26430 0000000000000000 0000000008000000 0000000000001000 0000000180010000 S    ?          0:02 sshd: aa@pts/24

Aby to naprawić (być może nie najlepsze rozwiązanie, działało dla mnie):

$ sudo apt-get install tcsh
[snip]
$ chsh -s /bin/tcsh
[connect in with a new connection, leave the old one open in case of any issues with tcsh]
$ sudo /etc/init.d/ssh restart

I to jest naprawione.

Twoje zdrowie!

NuclearDog
źródło
1

Spróbuj tego. Robić

bash$ shopt -s checkwinsize

w powłoce, a następnie zmień rozmiar okna terminala.

gjvc
źródło
2
Witamy w ServerFault. Czy zauważyłeś, że użytkownik rozwiązał już ten problem lata temu?
pisklęta
1
Wyglądało to na obejście dla mnie za pomocą tcsh zamiast bash.
gjvc