Debian SSH - Cambiar el tamaño del terminal no se registra con bash

11

Recientemente reinstalamos nuestro servidor debido a una falla del disco, y ahora tenemos un problema con el cambio de tamaño de las terminales. Instalamos Debian 6.0.6.

Síntomas

Cuando cambia el tamaño de un terminal, no parece que las aplicaciones basadas en ncurses (probadas: ytalk, irssi, screen, tmux, algunas de las aplicaciones de ejemplo de ncurses) cambien de tamaño correctamente. La pantalla generalmente termina en blanco. Forzar un nuevo dibujo en la aplicación se volverá a dibujar usando el tamaño de terminal anterior.

Al cambiar el tamaño de una ventana en un indicador bash (4.1.5 (1)), las variables COLUMNS y LINES nunca se actualizan.

Diagnósticos

Intentando atrapar al SIGWINCH en golpe, parece que nunca se está recibiendo. Esto fue probado con:

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

Lo que debería haber creado ambos archivos en mi directorio de inicio. Solo se creó /home/user/sigusr1.

Intentar kill -s SIGWINCH $$no causa una actualización de las variables $ COLUMNS / $ LINES.

Habilitar checkwinsize( shopt -s checkwinsize) hará que bash actualice $ COLUMNS / $ LINES al regresar de cualquier aplicación (como se esperaba). Esto lleva a lo siguiente después de cambiar el tamaño de un terminal con checkwinsizehabilitado:

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

Cambiar mi shell de inicio de sesión a algo como tcsh e intentar cambiar el tamaño del terminal funciona como se esperaba, al igual que bash en otras cajas que probé.

Intenté eliminar mi .bashrc y no hizo nada. Este problema está ocurriendo para otros usuarios con diferentes configuraciones de bash tanto en PuTTY como en algún tipo de terminal de tipo rxvt desde una caja de Linux.

strace

Corrí strah en bash e intenté cambiar el tamaño del terminal, no pasó nada (permaneció bloqueado en una readllamada inmediatamente después de imprimir el mensaje).

Apreté regresar en una línea vacía, y bash hizo un montón de cosas. El resultado que creo que es relevante es: ( versión completa )

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,

Lo que muestra bash, a mi entender: (podría estar malentendiendo esto horriblemente. Estoy fuera de mi elemento aquí).

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.

Esta misma versión realizada en una caja sin estos problemas (Ubuntu, bash 4.2.24 (1)) resultó en:

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,

Pregunta

¿Qué demonios está pasando y por qué se rompe mi fiesta? :(

Supongo que probablemente solo haya una opción en algún lugar que por defecto sea algo inesperado, pero las horas en Google no han resultado nada.

Cualquier ayuda y / o punteros son muy apreciados. Esto es realmente frustrante.

Gracias.

NuclearDog
fuente
No eres el primero: lists.gnu.org/archive/html/bug-bash/2007-01/msg00084.html Si a exec bashmano (por lo que ya no es un shell de inicio de sesión), ¿todavía se comporta mal? Si no, ¿qué pasa exec bash -l(entonces es un shell de inicio de sesión)? Si es así, entonces algo pasa con tus scripts de inicio de sesión ( /etc/profile /etc/profile.d/ ~/.bash_profile ~/.profile), pero ni siquiera sé qué decirte que busques, eso puede decirle al shell que no lo haga SIGWINCH.
DerfK
Ambos exec bashy exec bash -lexhiben el mismo comportamiento. Supongo que es un pequeño consuelo que no estoy solo en esto. Sin embargo, estoy completamente confundido sobre qué podría causar esto. El colo instaló una instalación mínima desde una imagen de Debian recién descargada. Tendré que intentar instalarlo localmente y ver si hay algún problema y (suponiendo que ninguno, ya que esto parece no ocurrirle a otras personas), comenzar a comparar con el sistema en ejecución.
NuclearDog
Hice una nueva instalación en una máquina virtual, generé una lista de sumas md5 de todos los archivos en / etc y / usr y comparé con el sistema dañado. A simple vista, no puedo ver nada obviamente malo. /etc/bash.bashrcy todos los archivos /etc/profiley /etc/profile.dno se modifican desde una instalación limpia. He descargado la fuente bash ( apt-get source bash) y estoy jugando con varios argumentos ./configurepara tratar de reducir el problema antes de profundizar en la fuente.
NuclearDog
--disable-readline --enable-minimal-config --disable-job-controlCompilé bash menos todos los parches de Debian , ejecuté una secuencia para ver qué archivos tenía open, renombré todos esos archivos y luego volví a iniciar sesión. Mismo problema. Definitivamente descarté cualquier cambio de configuración con bash.
NuclearDog
He replicado el mismo problema con bash 3.2, 4.1 y 4.2 compilado de fuentes recuperadas directamente de GNU. No pude compilar 4.2 sin control de trabajo y con una configuración mínima debido a algunos errores (informado al equipo bash). Dado que esto ocurre con varias versiones de bash, estoy empezando a creer que el error puede estar en una de las bibliotecas de las que depende. Pasando a eso.
NuclearDog

Respuestas:

11

Algo me había estado molestando sobre la salida de strace. Es decir, que parecía que cuando comenzó bash, parecía que ya tenía SIGWINCH enmascarado. No podía estar seguro, no entendía la mitad de lo que escupía, pero ciertamente valía la pena explorarlo en este momento.

Corrí strace -o strace_file bash -ldesde un shell tcsh, donde el problema no estaba presente. bash nunca enmascaró SIGWINCH. Cuando lo estaba enmascarando, era solo porque intentaba restaurar la máscara anterior. Entonces, ¿de dónde viene la máscara inicial?

Un poco más de tiempo en Google y una mente fresca y encontré esta publicación que mencionaba que la aptitud a veces puede hacer que sshd se inicie con SIGWINCH enmascarado, y que luego será heredado por todos los procesos generados directamente hasta el shell.

Lo intenté ps axwwws(todo, separado, salida amplia, señales). Mostró que varios de los procesos sshd generados tenían SIGWINCH enmascarado.

El servidor / proceso de escucha (sshd) no lo hizo. Tampoco los procesos que alojaban conexiones que usaban tcsh. Esa parte es confusa para mí. Supongo (una vez más, sabiendo muy poco sobre esto) que la máscara de señal es de todo el grupo de procesos o algo así, tcsh la reiniciaba al inicio, y eso también estaba afectando a ssh.

Entonces, por capricho, me conecté con tcsh (para obtener un término limpio sin máscara SIGWINCH), reinicié ssh, cambié mi shell a bash ... ¡Y funcionó! ¡Todo ha vuelto a la normalidad!

Hasta donde sé, aptitude no se ha ejecutado en este cuadro, y ssh se ha reiniciado varias veces para los cambios de configuración. Sin embargo, en algún lugar a lo largo de la línea, la máscara se abrió paso e infectó todo como una enfermedad grave.

Para reconocer el mismo problema, ejecute ps axwwws | grep sshdy busque procesos sshd con la segunda columna larga ( BLOCKED) que tiene 0x8000000 establecido. Eso es SIGWINCH. Algo como:

   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

Para solucionarlo (posiblemente no sea la mejor solución, funcionó para mí):

$ 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

Y está arreglado.

¡Salud!

NuclearDog
fuente
1

Prueba esto. Hacer

bash$ shopt -s checkwinsize

en su shell, luego cambie el tamaño de su ventana de terminal.

gjvc
fuente
2
Bienvenido a ServerFault. ¿Notó que el usuario ya había resuelto este problema hace años?
pollitos
1
Me pareció una solución alternativa usando tcsh en lugar de bash.
gjvc