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

11

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

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

Спасибо.

NuclearDog
источник
Вы не первый один: lists.gnu.org/archive/html/bug-bash/2007-01/msg00084.html Если вы exec bashвручную (так что это уже не Войти оболочки) делает это еще шалить? Если нет, то как насчет exec bash -l(так что это оболочка входа в систему)? Если так, то что-то не так с вашими скриптами входа в систему ( /etc/profile /etc/profile.d/ ~/.bash_profile ~/.profile), но я даже не знаю, что сказать вам, чтобы искать, что может сказать оболочке не делать этого SIGWINCH.
DerfK
Оба exec bashи exec bash -lдемонстрируют одинаковое поведение. Я полагаю, это небольшое утешение, что я не одинок в этом. Я полностью смущен относительно того, что могло бы вызвать это, все же. Colo установил минимальную установку из только что загруженного образа Debian. Мне придется попробовать установить локально и посмотреть, есть ли какие-то проблемы и (если нет, так как этого не происходит для других людей), начать сравнивать с работающей системой.
NuclearDog
Я сделал новую установку на ВМ, сгенерировал список md5 сумм всех файлов в / etc и / usr и сравнил их со сломанной системой. На первый взгляд, я не вижу ничего заведомо неправильного. /etc/bash.bashrcи все , /etc/profileи /etc/profile.dфайлы не изменяются от чистой установки. Я скачал bash source ( apt-get source bash) и играю с различными аргументами, ./configureчтобы попытаться сузить проблему, прежде чем копаться в источнике.
NuclearDog
Я скомпилировал bash минус все патчи Debian --disable-readline --enable-minimal-config --disable-job-control, выполнил команду strace, чтобы посмотреть, к каким файлам он openбыл переименован, переименовал все эти файлы и снова вошел в систему. Та же проблема. Я определенно исключил любые изменения конфигурации самого bash.
NuclearDog
Я повторил ту же проблему с bash 3.2, 4.1 и 4.2, скомпилированным из источников, полученных непосредственно из GNU. Я не смог скомпилировать 4.2 без управления заданиями и с минимальной конфигурацией из-за некоторых ошибок (сообщено команде bash). Учитывая, что это происходит с несколькими версиями bash, я начинаю верить, что ошибка может быть связана с одной из библиотек, от которых она зависит. Переходя к этому.
NuclearDog

Ответы:

11

Что-то не давало мне покоя по поводу вывода строк. А именно, казалось, что когда 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

И это исправлено.

Ура!

NuclearDog
источник
1

Попробуй это. Делать

bash$ shopt -s checkwinsize

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

gjvc
источник
2
Добро пожаловать в ServerFault. Вы заметили, что пользователь уже решил эту проблему несколько лет назад?
цыплята
1
Выглядело как обходной путь для меня, используя tcsh вместо bash.
GJVC