Debian SSH - терминал изменения размера не регистрируется в bash

Мы недавно переустановили наш сервер из-за сбоя диска, и теперь у нас возникла проблема с изменением размера терминалов. Мы установили 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 на bash и попытался изменить размер терминала, ничего не получилось (он остался заблокированным на read звоните сразу после распечатки приглашения).

Я нажал return в пустой строке, и bash сделал кучу всего. Вывод, который я считаю релевантным:

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 ничего не дали.

Любая помощь и / или указатели очень ценятся. Это действительно расстраивает.

Спасибо.

2 ответа

Решение

Что-то не давало мне покоя по поводу выхода strace. А именно то, что казалось, что когда началась bash, казалось, что SIGWINCH уже замаскирован. Не мог быть уверен, не понимал половину того, что он выплевывал, но это, безусловно, того стоило.

Я побежал strace -o strace_file bash -l из оболочки tcsh, где проблемы не было. Баш никогда не маскируется 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

в вашей оболочке, затем измените размер окна терминала.

Другие вопросы по тегам