Недавно мы переустановили наш сервер из-за сбоя диска, и теперь у нас возникла проблема с изменением размера терминалов. Мы установили Debian 6.0.6.
Симптомы
Когда вы изменяете размер терминала, никакие приложения на основе ncurses (проверенные: ytalk, irssi, screen, tmux, некоторые из примеров приложений ncurses) не изменяют размер правильно. Экран обычно остается пустым. Принудительная перерисовка в приложении приведет к перерисовке с использованием старого размера терминала.
При изменении размера окна в приглашении bash (4.1.5 (1)) переменные COLUMNS и LINES никогда не обновляются.
Диагностика
Попытка перехватить SIGWINCH в bash, кажется, никогда не принимается. Это было протестировано с помощью:
trap 'touch /home/user/sigwinch' SIGWINCH
trap 'touch /home/user/sigusr1' SIGUSR1
kill -s SIGWINCH $$
kill -s SIGUSR1 $$
Что должно было создать оба файла в моем домашнем каталоге. Он только создал /home/user/sigusr1
.
Пытаясь kill -s SIGWINCH $$
не вызывает обновления переменных $ COLUMNS / $ LINES.
Включение checkwinsize
(shopt -s checkwinsize
) заставит bash обновить $ COLUMNS / $ LINES при возврате из любого приложения (как и ожидалось). Это приводит к следующему после изменения размера терминала с помощью checkwinsize
включен:
$ echo $COLUMNS ; ls > /dev/null ; echo $COLUMNS
72
107
Изменение моей оболочки входа на что-то вроде tcsh и попытка изменить размер терминала работают должным образом, как и bash в других тестируемых мной ящиках.
Я попытался удалить свой .bashrc, но ничего не сделал. Эта проблема возникает у нескольких других пользователей с различными конфигурациями bash как в PuTTY, так и в каком-то терминале типа rxvt из Linux.
Strace
Я запустил strace на bash и попытался изменить размер терминала, ничего не вышло (он остался заблокированным на read
позвоните сразу после печати подсказки).
Я нажимаю return на пустой строке, и bash проделал целую кучу вещей. Вывод, который я считаю актуальным: (полный Strace)
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,
Который показывает bash, насколько я понимаю: (Я могу ужасно неправильно это понять. Я здесь не в своей тарелке.)
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.
Тот же самый strace, выполненный на коробке без этих проблем (Ubuntu, bash 4.2.24 (1)), привел к:
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,
Вопрос
Что, черт возьми, происходит и почему мой баш сломан? :(
Я предполагаю, что где-то есть опция, которая по умолчанию привела к чему-то неожиданному, но часы в Google ничего не дали.
Любая помощь и / или указатели приветствуются. Это действительно расстраивает.
Спасибо.
Что-то меня беспокоило в выводе strace. А именно то, что казалось, что когда bash запускался, казалось, что SIGWINCH уже был замаскирован. Не мог быть уверен, не понимал половины того, что он выплевывал, но на этом этапе определенно стоило исследовать.
Я побежал strace -o strace_file bash -l
из оболочки tcsh, где проблемы не было. bash никогда не маскировал SIGWINCH. Когда он маскировал его, это было только потому, что он пытался восстановить предыдущую маску. Так откуда же взялась первоначальная маска?
Еще немного времени в Google и свежих мыслей, и я нашел эта почта в котором упоминалось, что aptitude может иногда вызывать запуск sshd с замаскированным SIGWINCH, а затем он будет унаследован всеми порожденными процессами прямо до оболочки.
Я попытался ps axwwws
(все, отдельно, широкий выход, сигналы). Он показал, что у нескольких порожденных процессов sshd был замаскирован SIGWINCH.
Процесс сервера / прослушивания (сам sshd) не работал. Так же как и процессы, которые размещали соединения, которые использовали tcsh. Эта часть меня сбивает с толку. Я предполагаю (опять же, зная об этом очень мало), что маска сигнала является всей группой процессов или что-то в этом роде, tcsh сбрасывал ее при запуске, и это также влияло на ssh.
Итак, по прихоти я подключился к tcsh (чтобы получить чистый термин без маски SIGWINCH), перезапустил ssh, снова сменил оболочку на bash ... И это сработало! Все вернулось в норму!
Насколько я знаю, aptitude не запускался на этом компьютере, и ssh несколько раз перезапускался для изменения конфигурации. Но где-то по пути маска пробилась и заразила все, как тяжелая болезнь.
Чтобы распознать ту же проблему, запустите ps axwwws | grep sshd
и ищите процессы sshd со вторым длинным столбцом (BLOCKED
) имеет значение 0x8000000. Это SIGWINCH. Что-то вроде:
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
Чтобы исправить это (возможно, не лучшее решение, сработало для меня):
$ 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
И это исправлено.
Ура!
Попробуй это. Делать
bash$ shopt -s checkwinsize
в вашей оболочке, а затем измените размер окна терминала.