Debian SSH - Le redimensionnement du terminal ne s'enregistre pas avec bash


11

Nous avons récemment réinstallé notre serveur en raison d'une panne de disque, et nous avons maintenant un problème avec le redimensionnement des terminaux. Nous avons installé Debian 6.0.6.

Symptômes

Lorsque vous redimensionnez un terminal, aucune application basée sur ncurses (testée: ytalk, irssi, screen, tmux, certaines des applications d'exemple ncurses) ne semble redimensionner correctement. L'écran finit généralement vide. Forcer un nouveau dessin dans l'application sera redessiné en utilisant l'ancienne taille du terminal.

Lors du redimensionnement d'une fenêtre à l'invite bash (4.1.5 (1)), les variables COLUMNS et LINES ne sont jamais mises à jour.

Diagnostique

Tentant de piéger le SIGWINCH dans bash, il semble qu'il ne soit jamais reçu. Cela a été testé avec:

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

Qui aurait dû créer les deux fichiers dans mon répertoire personnel. Il a seulement créé /home/user/sigusr1.

Tenter de kill -s SIGWINCH $$ne provoque pas de mise à jour des variables $ COLUMNS / $ LINES.

L'activation de checkwinsize( shopt -s checkwinsize) obligera bash à mettre à jour $ COLUMNS / $ LINES au retour de n'importe quelle application (comme prévu). Cela conduit aux éléments suivants après avoir redimensionné un terminal avec checkwinsizeactivé:

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

Changer mon shell de connexion en quelque chose comme tcsh et essayer de redimensionner le terminal fonctionne comme prévu, tout comme bash sur d'autres boîtes que j'ai testées.

J'ai essayé de supprimer mon .bashrc et cela n'a rien fait. Ce problème se produit pour plusieurs autres utilisateurs avec différentes configurations bash dans PuTTY et une sorte de terminal de type rxvt à partir d'une boîte Linux.

strace

J'ai exécuté strace sur bash et j'ai essayé de redimensionner le terminal, rien ne l'a traversé (il est resté bloqué lors d'un readappel immédiatement après l'impression de l'invite).

J'ai frappé retour sur une ligne vide, et bash a fait tout un tas de trucs. Le résultat que je pense être pertinent est: ( full 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,

Ce qui montre bash, à ma compréhension: (Je pourrais être horriblement mal compris. Je suis loin de mon élément ici.)

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.

Cette même séquence effectuée sur une boîte sans ces problèmes (Ubuntu, bash 4.2.24 (1)) a entraîné:

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,

Question

Que diable se passe-t-il et pourquoi ma bash est-elle cassée? :(

Je suppose qu'il y a probablement juste une option quelque part qui s'est transformée en quelque chose d'inattendu, mais les heures sur Google n'ont rien révélé.

Toute aide et / ou pointeurs sont grandement appréciés. C'est vraiment frustrant.

Je vous remercie.


Vous n'êtes pas le premier: lists.gnu.org/archive/html/bug-bash/2007-01/msg00084.html Si vous exec bashà la main (donc ce n'est plus un shell de connexion) se comporte-t-il toujours mal? Sinon, qu'en est-il exec bash -l(c'est donc un shell de connexion)? Si c'est le cas, alors quelque chose ne va pas avec vos scripts de connexion ( /etc/profile /etc/profile.d/ ~/.bash_profile ~/.profile), mais je ne sais même pas quoi vous dire de rechercher qui peut dire au shell de ne pas le faire SIGWINCH.
DerfK

Les deux exec bashet exec bash -lprésentent le même comportement. Je suppose que c'est une petite consolation que je ne sois pas le seul. Je suis profondément confus quant à ce qui pourrait provoquer cela, cependant. Le colo a installé une installation minimale à partir d'une image Debian fraîchement téléchargée. Je vais devoir essayer d'installer localement et voir s'il y a des problèmes et (en supposant qu'aucun, car cela ne semble pas se produire pour d'autres personnes), commencer à comparer avec le système en cours d'exécution.
NuclearDog

J'ai fait une nouvelle installation dans une machine virtuelle, généré une liste des sommes md5 de tous les fichiers dans / etc et / usr et comparé au système cassé. En un coup d'œil, je ne vois rien de mal à l'évidence. /etc/bash.bashrcet tous les fichiers /etc/profileet /etc/profile.dsont inchangés à partir d'une nouvelle installation. J'ai téléchargé la source bash ( apt-get source bash) et je joue avec divers arguments ./configurepour essayer de réduire le problème avant de creuser dans la source.
NuclearDog

J'ai compilé bash moins tous les correctifs Debian avec --disable-readline --enable-minimal-config --disable-job-control, exécuté une strace pour voir quels fichiers il avait open, renommé tous ces fichiers, puis connecté à nouveau. Même problème. J'ai assez certainement exclu tout changement de configuration avec bash lui-même.
NuclearDog

J'ai reproduit le même problème avec bash 3.2, 4.1 et 4.2 compilés à partir de sources récupérées directement depuis GNU. Je n'ai pas pu compiler 4.2 sans contrôle de travail et avec une configuration minimale en raison de quelques bugs (signalés à l'équipe bash). Étant donné que cela se produit avec plusieurs versions de bash, je commence à croire que l'erreur peut provenir d'une des bibliothèques dont elle dépend. Passons à cela.
NuclearDog

Réponses:


11

Quelque chose m'avait mis sur écoute à propos de la sortie strace. À savoir qu'il semblait que lorsque bash a commencé, il semblait qu'il avait déjà masqué SIGWINCH. Je ne pouvais pas en être sûr, je ne comprenais pas la moitié de ce qu'il crachait, mais cela valait certainement la peine d'être exploré à ce stade.

J'ai couru à strace -o strace_file bash -lpartir d'un shell tcsh, où le problème n'était pas présent. bash n'a jamais masqué SIGWINCH. Quand il le masquait, c'était uniquement parce qu'il tentait de restaurer le masque précédent. D'où venait donc le masque initial?

Un peu plus de temps sur Google et un esprit neuf et j'ai trouvé ce post qui mentionnait que l'aptitude peut parfois provoquer le démarrage de sshd avec SIGWINCH masqué, et qu'il sera ensuite hérité par tous les processus générés directement vers le shell.

J'ai essayé ps axwwws(tout, détaché, sortie large, signaux). Il a montré que plusieurs des processus sshd engendrés avaient masqué SIGWINCH.

Le processus serveur / écoute (sshd lui-même) ne l'a pas fait. Les processus qui hébergeaient les connexions utilisant tcsh ne le faisaient pas non plus. Cette partie me déroute. Je suppose (encore une fois, en sachant très peu de choses sur tout cela) que le masque de signal est à l'échelle du groupe de processus ou quelque chose, tcsh le réinitialisait au démarrage, et cela affectait également ssh.

Donc, sur un coup de tête, je me suis connecté avec tcsh (pour obtenir un terme propre sans masque SIGWINCH), redémarré ssh, changé mon shell en bash ... Et cela a fonctionné! Tout est revenu à la normale!

Autant que je sache, aptitude n'a pas été exécuté sur cette boîte et ssh a été redémarré plusieurs fois pour des changements de configuration. Quelque part le long de la ligne, le masque a fait son chemin, cependant, et a tout infecté comme une mauvaise maladie.

Pour reconnaître le même problème, exécutez ps axwwws | grep sshdet recherchez les processus sshd avec la deuxième longue colonne ( BLOCKED) a 0x8000000 défini. C'est SIGWINCH. Quelque chose comme:

   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

Pour le réparer (peut-être pas la meilleure solution, a fonctionné pour moi):

$ 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

Et c'est réparé.

À votre santé!


1

Essaye ça. Faire

bash$ shopt -s checkwinsize

dans votre shell, puis redimensionnez votre fenêtre de terminal.


2
Bienvenue sur ServerFault. Avez-vous remarqué que l'utilisateur avait déjà résolu ce problème il y a des années?
poussins

1
Cela ressemblait à une solution de contournement pour moi en utilisant tcsh au lieu de bash.
gjvc
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.