Debian SSH - O redimensionamento do terminal não se registra no bash

11

Recentemente, reinstalamos o servidor devido a uma falha no disco e agora estamos tendo um problema ao redimensionar os terminais. Instalamos o Debian 6.0.6.

Sintomas

Quando você redimensiona um terminal, nenhum aplicativo baseado em ncurses (testado: ytalk, irssi, screen, tmux, alguns dos aplicativos de exemplo ncurses) parece redimensionar corretamente. A tela geralmente fica em branco. Forçar um redesenho no aplicativo será redesenhado usando o tamanho do terminal antigo.

Ao redimensionar uma janela em um prompt do bash (4.1.5 (1)), as variáveis ​​COLUMNS e LINES nunca são atualizadas.

Diagnóstico

Tentando interceptar o SIGWINCH no bash, parece que ele nunca está sendo recebido. Isso foi testado com:

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

O que deveria ter criado os dois arquivos no meu diretório pessoal. Apenas criou /home/user/sigusr1.

Tentar kill -s SIGWINCH $$não causa uma atualização das variáveis ​​$ COLUMNS / $ LINES.

Ativar checkwinsize( shopt -s checkwinsize) fará com que o bash atualize $ COLUMNS / $ LINES ao retornar de qualquer aplicativo (conforme o esperado). Isso leva ao seguinte após o redimensionamento de um terminal com checkwinsizeativado:

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

Alterar meu shell de login para algo como tcsh e tentar redimensionar o terminal funciona como esperado, assim como o bash em outras caixas que testei.

Tentei remover o meu .bashrc e ele não fez nada. Esse problema está ocorrendo para vários outros usuários com configurações de bash variadas no PuTTY e em algum tipo de terminal do tipo rxvt em uma caixa do Linux.

traço

Corri o strace no bash e tentei redimensionar o terminal, nada aconteceu (ele permaneceu bloqueado em uma readligação imediatamente após a impressão do prompt).

Apertei return em uma linha vazia e o bash fez um monte de coisas. A saída que acredito ser relevante é: ( rastreamento completo )

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,

O que mostra bash, para meu entendimento: (eu poderia estar terrivelmente mal entendendo isso. Estou fora do meu elemento aqui.)

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.

Esse mesmo rastreamento realizado em uma caixa sem esses problemas (Ubuntu, bash 4.2.24 (1)) resultou em:

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,

Questão

O que diabos está acontecendo e por que minha festança está quebrada? :(

Suponho que provavelmente haja apenas uma opção em algum lugar que tenha adotado algo inesperado, mas as horas no Google não resultaram em nada.

Qualquer ajuda e / ou sugestões são muito apreciadas. Isso é realmente frustrante.

Obrigado.

NuclearDog
fonte
Você não é o primeiro: lists.gnu.org/archive/html/bug-bash/2007-01/msg00084.html Se você exec bashmanualmente (para que não seja mais um shell de login), ele ainda se comporta mal? Caso contrário, o que dizer exec bash -l(então é um shell de login)? Nesse caso, algo está acontecendo com seus scripts de login ( /etc/profile /etc/profile.d/ ~/.bash_profile ~/.profile), mas eu nem sei o que dizer para você procurar, o que pode dizer ao shell SIGWINCH.
DerfK 26/11/12
Ambos exec bashe exec bash -lexibem o mesmo comportamento. Suponho que seja um pequeno consolo que eu não esteja sozinho nisso. Estou completamente confuso sobre o que causaria isso, no entanto. O colo instalou uma instalação mínima a partir de uma imagem recém-baixada do Debian. Vou ter que tentar instalar localmente e ver se há algum problema e (assumindo que não, já que isso parece não acontecer para outras pessoas), comece a comparar com o sistema em execução.
NuclearDog
Fiz uma nova instalação em uma VM, gere uma lista de somas md5 de todos os arquivos em / etc e / usr e comparei com o sistema danificado. De relance, não vejo nada obviamente errado. /etc/bash.bashrce todos os arquivos /etc/profilee /etc/profile.dpermanecem inalterados em uma instalação limpa. Eu baixei o bash source ( apt-get source bash) e estou jogando com vários argumentos ./configurepara tentar diminuir o problema antes de ir para o código-fonte.
precisa
Eu compilei o bash menos todos os patches do Debian --disable-readline --enable-minimal-config --disable-job-control, corri um rastro para ver quais arquivos ele havia openrenomeado, renomeou todos esses arquivos e depois loguei novamente. O mesmo problema. Definitivamente, eliminei quaisquer alterações na configuração com o próprio bash.
precisa
Eu repliquei o mesmo problema com o bash 3.2, 4.1 e 4.2 compilado a partir de fontes recuperadas diretamente do GNU. Não consegui compilar o 4.2 sem o controle do trabalho e com a configuração mínima devido a alguns erros (relatados à equipe do bash). Dado que isso ocorre com várias versões do bash, estou começando a acreditar que o erro pode estar em uma das bibliotecas das quais depende. Passando para isso.
precisa

Respostas:

11

Algo estava me incomodando na saída do strace. Nomeadamente, parecia que quando o bash começou, parecia que o SIGWINCH já estava mascarado. Não podia ter certeza, não entendia metade do que estava cuspindo, mas certamente valia a pena explorar neste momento.

Corri strace -o strace_file bash -lde um shell tcsh, onde o problema não estava presente. bash nunca mascarou SIGWINCH. Quando estava mascarando, era apenas porque estava tentando restaurar a máscara anterior. Então, de onde vinha a máscara inicial?

Um pouco mais de tempo no Google e com uma mente renovada, encontrei este post que mencionava que o aptitude às vezes pode causar o sshd ser iniciado com o SIGWINCH mascarado, e que será herdado por todos os processos gerados diretamente para o shell.

Eu tentei ps axwwws(tudo, destacado, saída ampla, sinais). Ele mostrou que vários dos processos sshd gerados tinham o SIGWINCH mascarado.

O processo do servidor / escuta (o próprio sshd) não o fez. Nem os processos que hospedavam conexões que usavam o tcsh. Essa parte é confusa para mim. Eu estou supondo (novamente, sabendo muito pouco sobre isso) que a máscara de sinal é do grupo de processos ou algo assim, o tcsh estava redefinindo no início, e isso estava afetando o ssh também.

Então, por um capricho, me conectei com o tcsh (para obter um termo limpo sem máscara SIGWINCH), reiniciei o ssh, mudei meu shell de volta para o bash ... E funcionou! Tudo voltou ao normal!

Até onde eu sei, o aptitude não foi executado nesta caixa e o ssh foi reiniciado algumas vezes para alterações na configuração. Em algum lugar ao longo da linha, a máscara entrou e infectou tudo como uma doença ruim.

Para reconhecer o mesmo problema, execute ps axwwws | grep sshde procure processos sshd com a segunda coluna longa ( BLOCKED) com 0x8000000 definido. Isso é 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 corrigi-lo (possivelmente não a melhor solução, funcionou para mim):

$ 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

E está consertado.

Felicidades!

NuclearDog
fonte
1

Tente isso. Faz

bash$ shopt -s checkwinsize

no seu shell e redimensione sua janela do terminal.

gjvc
fonte
2
Bem-vindo ao ServerFault. Você notou que o usuário já havia resolvido esse problema anos atrás?
pintainhos
1
Parecia uma solução alternativa para mim usando o tcsh em vez do bash.
Gjvc #