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 checkwinsize
włą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 read
połą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.
exec bash
ręcznie (więc nie jest to już powłoka logowania), to nadal źle się zachowuje? Jeśli nie, to co zexec 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 nieSIGWINCH
.exec bash
iexec bash -l
wykazują 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./etc/bash.bashrc
a wszystkie pliki/etc/profile
i/etc/profile.d
pozostają niezmienione od czystej instalacji. Pobrałem bash source (apt-get source bash
) i gram z różnymi argumentami,./configure
aby spróbować zawęzić problem przed kopaniem do źródła.--disable-readline --enable-minimal-config --disable-job-control
, uruchomiłem śledzenie, by zobaczyć, które to plikiopen
, 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.Odpowiedzi:
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 -l
z 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 sshd
i wyszukaj procesy sshd z drugą długą kolumną (BLOCKED
) ma ustawiony 0x8000000. To jest SIGWINCH. Coś jak:Aby to naprawić (być może nie najlepsze rozwiązanie, działało dla mnie):
I to jest naprawione.
Twoje zdrowie!
źródło
Spróbuj tego. Robić
w powłoce, a następnie zmień rozmiar okna terminala.
źródło