Problema
Eu executo um comando que gera muitas informações através do SSH. Por exemplo, tolamente adiciono informações de depuração dentro de um loop que é executado milhões de vezes, ou apenas executado cat /dev/urandom
por chutes.
O terminal está inundado de informações.
Quero finalizar o comando o mais rápido possível e corrigir meu programa. Eu não ligo para o que imprime. Agora, pressione Ctrl+ CASAP (no exemplo acima, pressionei-o imediatamente após executar o comando), mas ainda leva tempo para imprimir todas as informações de que não preciso .
O que eu tentei
Tentei pressionar Ctrl+ com Ctanta força que teve resultados engraçados quando o terminal finalmente alcançou:
OUTPUT HERE^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
^C^C
^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
Eu também li sobre Ctrl+, Sque aparentemente é usado para dizer ao terminal "parar a saída, preciso recuperar o atraso", mas aparentemente não faz nada.
Detalhes diversos
Gostaria de não alterar o comando que executo para que eu possa me resgatar em qualquer situação, mesmo que não me lembre de que o programa executado pode acabar assim.
Meu cliente SSH é executado no Cygwin ( CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin
) no MinTTY com o tipo de terminal definido como xterm-256color
.
O servidor SSH é executado no Debian ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux
).
Ctrl-O
, o que significa "descartar qualquer saída gravada neste terminal".-j
opção, para ativar a rolagem de salto. O problema básico é que o controle remoto pode enviar dados mais rapidamente do que a janela do terminal pode exibi-los - por padrão, ele deve bitblt o conteúdo da janela toda vez que uma nova linha é impressa. Muitos dados podem ser armazenados em buffer no momento em que seu Ctrl-C é recebido pelo sistema remoto, e seu programa de terminal tenta exibir todos eles..bashrc
?Respostas:
Parte dessa saída será armazenada em buffer. Você envia seu Ctrl+ Cpara a extremidade remota, que interrompe o programa em execução. O programa existe e o shell envia os caracteres para mostrar o prompt novamente. Antes que o prompt seja exibido, sua tela mostrará primeiro todos os dados que foram armazenados em buffer e que já estão a caminho.
O que você está pedindo é que o programa pare e os dados em trânsito desapareçam de alguma forma. Isso não pode acontecer, pois já está a caminho.
A única maneira de garantir que você não veja esses dados é sair do terminal e reconectar-se ao seu controle remoto - mas isso é provavelmente muito mais esforço do que aguardar a exibição dos dados em buffer.
fonte
Normalmente, eu executo a saída
less
para que eu possa matá-laless
usando a qchave.Exemplo
Depois de pressionar q+, Enterele sairá e voltará ao seu terminal normal, deixando-o agradável e limpo.
Por que isso acontece?
O problema que você está enfrentando é que existem buffers (para STDOUT) que estão sendo colocados na fila com a saída do seu monitor. Esses buffers são preenchidos tão rapidamente que você não consegue interrompê-lo rápido o suficiente para pará-lo.
Para desativar / limitar esse efeito, você pode desativar o buffer STDOUT, o que deve tornar as coisas um pouco mais responsivas
stdbuf
, mas você provavelmente precisará brincar com essas configurações para obter as coisas da maneira que desejar. Para remover o buffer do STDOUT, você pode usar este comando:A página de manual para
stdbuf
detalhes das opções à sua disposição:Para um bom histórico de como o buffer funciona, eu sugiro dar uma olhada neste Pixel Beat articulado intitulado: buffering em fluxos padrão . Inclusive inclui belas fotos.
Referências
fonte
|less
quecmd
, o que, infelizmente, muitas vezes não o fazem. Se você executarcmd
, ainda precisará aguardar até que a impressão dos resultados seja concluída antes de receber^C
.Existem vários níveis de buffer. Quando você pressiona Ctrl+ C, isso impede que o programa emita dados para o terminal. Isso não afeta os dados que o emulador de terminal ainda não exibiu.
Quando você exibe dados em velocidade muito alta, o terminal não consegue acompanhar e fica atrasado. É isso que está acontecendo aqui: exibir texto é muito mais caro do que produzir esses números aleatórios. Sim, mesmo com uma fonte de bitmap - produzir números aleatórios com qualidade criptográfica é muito barato em comparação. (Acabei de experimentar na minha máquina e o processo X saturou a CPU, com
xterm
alguns% ecat
(contra os quais a geração de números aleatórios é considerada) mal atingindo 1%. E isso é com uma fonte de bitmap).Se você quiser que isso pare agora, mate o emulador de terminal. Se você não quiser fazer isso, pelo menos minimize a janela; emuladores de terminal inteligentes (como o xterm) não mapeiam a janela, o que economiza o tempo da CPU X, portanto o lixo terminará a exibição mais rapidamente. O servidor X tem alta prioridade, portanto, isso fará uma grande diferença na capacidade de resposta da sua máquina enquanto o xterm está processando os dados em segundo plano.
Quando tudo isso acontece em um shell remoto, o atraso é ainda pior, porque os dados produzidos por
cat
precisam primeiro passar pela conexão SSH. Sua pressão de Ctrl+ Ctambém precisa passar pela conexão SSH; obtém prioridade um pouco maior (é enviada para fora da banda), mas isso ainda leva algum tempo durante o qual mais saída se acumula. Não há como suprimir dados em trânsito antes de fechar a conexão SSH (o que você pode fazer pressionando Enterentão~.
).fonte
Deve ser o suficiente para encontrar um caminho para
kill
ocat
comando.Para as propostas a seguir, você pode precisar de uma segunda conexão ssh aberta.
Raramente CTRL+zpode ser mais eficaz do que CTRL+c: pode responder mais rapidamente. Depois que você suspender o comando, poderá matá-lo com
kill %1
ou qualquer que seja o número do trabalho.Isso na esperança de que você ainda consiga ler qualquer coisa na tela (um texto binário aleatório pode inundar facilmente seu conjunto de caracteres).
Como lembrado por Gilles, se você minimizar a janela, provavelmente o sistema será mais rápido para ler a solicitação de interrupção do que para matar o processo. Portanto, suspender / interromper, minimizar, esperar um pouco, maximizar novamente, também pode ser uma solução.
Obviamente, através de uma conexão ssh, espero que você precise esperar um pouco.
Em outro terminal / sessão, você pode perguntar
pgrep cat
(se o comando cat foi chamado) e identificar o processo do gato usando mais sua CPU. Você pode identificá-lo com mais precisão compstree
:gato pgrep | awk '{print "pstree -sp" $ 1}' | sh | grep sshd
responda com uma saída como
O problema é que o problema não é o problema, mas o problema é o seguinte: `` O problema é que o problema não foi resolvido ''.
Nesse caso, depois que você tiver apenas que matar o gato PID: mate 23131
Nota:
less
é mais seguro.fonte
Eu tinha o mesmo problema e não estava satisfeito com as respostas aqui, então me aprofundou mais. Outros já mencionaram que seu comando está produzindo dados mais rapidamente do que o ssh pode suportar, portanto, os buffers de dados e os buffers não podem ser parados.
Para corrigir isso, evite armazenar em buffer limitando sua saída de comando para a taxa máxima que sua sessão ssh pode executar, já existem comandos para fazer isso.
Configuração, primeiro descubra a taxa máxima de suas sessões:
Finalmente, estrangule seus comandos reais de acordo.
Exemplo:
Você pode reduzir um pouco a TAXA caso a velocidade da sua conexão caia um pouco de tempos em tempos. Se cair, o comportamento retornará ao problema, um ctrl-c não responsivo.
Alias de gato otimizado opcional:
Agora, o ctrl-c funciona como esperado, eliminando imediatamente a saída, já que muito pouco ou nenhum é armazenado em buffer.
fonte
cat
A saída raramente está sendo um problema, diferente de outros softwares. O autor o usou apenas como exemplo. O problema geralmente ocorre devido a outro software, que pode não ser óbvio se estiver disposto a produzir muita saída. Usar qualquer tipo de comando prefixo ou postfix não é solução, pois leva tempo para digitá-lo. Não haverá nenhum ganho no resultado.Existe um software no Linux que resolve exatamente esse problema (algumas outras coisas também). Você também pode invocá-lo em um emulador de terminal no Windows (você parece estar usando o Windows?).
Tente mosh , um substituto para o binário SSH. Funciona exatamente como o SSH (você pode fazer em
mosh user@hostname
vez dessh user@hostname
e funcionaria exatamente como o esperado, fará até autenticação de chave privada etc.Basicamente, ele executa um processo separado no servidor que armazena em buffer os pacotes. Portanto, quando você pressiona Ctrl + C no mosh, ele o transmite ao servidor remoto, que interrompe o envio de informações extras. Além disso, ele também prevê o resultado do pressionamento de tecla, economizando alguns milissegundos toda vez que você pressiona uma tecla.
Desvantagem: atualmente não é possível rolar para cima no histórico enquanto estiver usando o mosh.
fonte