Os comandos Bash ficam truncados ao colar vários comandos no terminal

2

Eu copiei / colei as seguintes 100 linhas em meu terminal (xterm) para executá-las em um servidor ao qual estou conectado em ssh :

mv /long/path/to/file1 /longer/path/to/file1
mv /long/path/to/file2 /longer/path/to/file2
...
mv /long/path/to/file99 /longer/path/to/file99
mv /long/path/to/file100 /longer/path/to/file100

Infelizmente, depois da cópia / colagem, não consegui encontrar meus 100 arquivos em /longer/path/to/

Olhando para o histórico do bash no servidor que estou conectado ao ssh, vejo que após os primeiros 20 comandos, a maioria dos comandos ficou truncada:

mv /long/path/to/file1 /longer/path/to/file1
...
mv /long/path/to/file20 /longer/path/to/file20
mv /long/path/to/fi
mv /long/path/to/fi
mv /long/path/to/file23 /longer/p
mv /long/path/to/file24 /longer/path
mv /long/path/to/file25 /longer/p
mv /long/path/to/file26 /longer/p
mv /long/path/to/file27 /longer/path/t
mv /long/path/to/file28 /longer/path/to/fil
mv /long/path/to/file29 /longer/path/to/fil
mv /long/path/to/file30 /longer/path/to/file
mv /long/path/to/file31 /longer/path/to/file
...

Eu encontrei respostas sobre como solucionar esse problema:

Mas não consegui encontrar uma explicação sobre o que está acontecendo exatamente. Notavelmente:

  • é um problema relacionado ao terminal (Xterm no meu caso)?
  • o copiar / colar ocorre em ssh : isso gera ou amplia o problema?
  • é um problema relacionado ao bash no servidor? Não poderia acontecer com outra casca?
por Gohu 27.03.2018 / 15:14

3 respostas

3

Parece que você está com esse bug:

link

readline() inadvertently triggers an error recovery path when pastes larger than 4k overrun the line discipline buffer. The error recovery path discards input when the line discipline buffer is full and operating in canonical mode and no newline has been received. Because readline() changes the termios to non-canonical mode to read the line char-by-char, the line discipline buffer can become full, and then when readline() restores termios back to canonical mode for the caller, the now-full line discipline buffer triggers the error recovery.

When changing termios from non-canon to canon mode and the read buffer contains data, simulate an EOF push without the DISABLED_CHAR in the read buffer.

Importantly for the readline() problem, the termios can be changed back to non-canonical mode without changes to the read buffer occurring; ie., as if the previous termios change had not happened (as long as no intervening read took place).

Foi aplicado ao kernel em 10 de dezembro de 2013, que era o kernel linux 3.14. Você está usando alguma distribuição Linux mais antiga que isso? Qual é a sua distro? Você provavelmente substituiu o caminho real para o arquivo, por isso não posso contar os caracteres. Você poderia fazer:

for ((a=1; a<20; a++)); do echo "mv /long/path/to/file$a /longer/path/to/file$a"; done|wc -c

com seus caminhos reais - seria algo realmente próximo a 4k? Se sim, o erro acima provavelmente é seu.

Se assim for, responde às suas perguntas:

  • é um problema relacionado ao terminal (Xterm no meu caso)?

não

  • o copiar / colar ocorre sobre o ssh: isso gera ou amplia o problema?

não

  • é um problema relacionado ao bash no servidor?

Não e sim - isso não é um bug no bash ou qualquer lib usado pelo bash. Bug está no kernel.

  • Será que isso não aconteceria com outro shell?

Pode ser, se o shell não estiver usando readline. Como zsh.

Com relação a perguntas relacionadas "como colar vários ...", não parece relacionado ao seu problema. Por isso, alguns aplicativos podem ler os comandos que você colou. O exemplo mais conhecido é o ssh, se você executar o comando ssh no servidor remoto. Mas, dado que você perde apenas partes de linhas, é improvável no seu caso.

Segunda pergunta 'Comandos colados no terminal ...' perguntou em 25 de setembro de 2013, na época o patch não existia e definitivamente parece um bug que você tem e bug eu sou do kernel, eu suspeito.

Como verificar com certeza? cole a saída do uname -a aqui.

    
por 25.06.2018 / 12:18
0

Eu sugiro usar gzip e base64 para copiar o comando de um terminal para outro. Se o problema vier do metacaractere ou da expansão de tabulação, você deve superá-lo desta maneira.

Exemplo:

[root@server-one ~]# cat << __EOF__ | gzip | base64
mv /long/path/to/file23 /longer/p
mv /long/path/to/file24 /longer/path
mv /long/path/to/file25 /longer/p
<other commands>
__EOF__

Copie o resultado codificado para

[root@server-two ~]$ base64 -di | gunzip | bash
<insert your base64-encoded and send with control-d>
    
por 19.06.2018 / 18:05
0

Problema na mão

Você deseja saber por que suas linhas de código copiadas e coladas estão truncadas.

Analisei seu problema e descobri que o Bash normalmente tem um limite de linha por padrão. Este é provavelmente o seu problema. No entanto, os exemplos que você fornece mostram linhas sendo truncadas em diferentes comprimentos. Eu vou tentar o meu melhor para quebrar isso.

Solução

1. É um problema relacionado ao terminal (Xterm no meu caso)?

É bem possível, mas isso é devido às limitações de um ambiente Bash padrão não xterm. (A menos que você tenha alterado muitos padrões do xterm)

Estou referenciando os seguintes posts que oferecem soluções para aumentar o comprimento da linha para reduzir o truncamento. Esta resposta de troca de pilha U & L abrange a alteração do tamanho da janela para corresponder ao que o seu emulador de terminal espera. O usuário saketrp oferece isso como uma solução para garantir que o tamanho da sua janela seja interpretado corretamente pelo seu terminal.

If you are using bash, you can try this.

$ shopt checkwinsize

If you don't get

checkwinsize    on

Then activate it with

$ shopt -s checkwinsize

Then just attempt running another command (like ls) or resizing the window once, the above works for me every time.

For Redhat systems particularly, the issue is often caused by misconfiguring ~/.bashrc not to call /etc/bashrc. Normally, bash loads ~/.bashrc which is expected to call /etc/bashrc, which by default contains shopt -s checkwinsize.

No entanto, isso só afeta as interpretações do tamanho da janela e não do tamanho real da linha. Usando as informações fornecidas em esta postagem do AskUbuntu se você tiver shopt definido corretamente, poderá adicionar a seguinte linha ao seu .bashrc para aumentar o comprimento da linha.

COLUMNS=250

e execute source .bashrc para atualizar seu perfil do Bash.

2. o copiar / colar ocorre sobre o ssh: isso gera ou amplia o problema?

Eu diria que isso faz parte do problema, se não for parte da causa raiz. As soluções alternativas que você vinculou são soluções sólidas para evitar que isso aconteça.

Sugiro que se você precisar copiar e colar um conjunto de comandos (você precisa usá-los mais de uma vez?) crie um script Bash do conjunto de comandos. Em seguida, use scp , sftp , curl , email ou qualquer método para transferir arquivos remotamente que você deseja usar.

Isso evita totalmente o problema de truncamento, conforme descrito nas soluções alternativas vinculadas, e você pode até criar scripts para a criação e / ou transferência dos scripts para vários servidores de uma só vez.

3. É um problema relacionado ao bash no servidor? Isso não aconteceria com outra casca?

Como mencionado anteriormente, sim, isso pode ser um problema com os limites de linha definidos pelas configurações do perfil Bash. Outros shells podem não ter esse problema, mas eu só estou familiarizado com o Dash / Bash. No entanto, se esses forem servidores de produção ou sistemas legados, nem sempre ele poderá se exercitar se você começar a alterar variáveis de ambiente. Não quer dizer que não é impossível, no entanto, existem riscos se certos pacotes / software / scripts anteriores / cronjobs contam com Bash sendo o shell padrão, mudando isso pode ter consequências.

Mais uma vez, sugiro que você crie um script dos comandos que deseja executar e transfira-o para o servidor remoto a ser executado para solucionar esse problema.

Conclusão

Por que seus comandos estão sendo truncados depende do seu ambiente, das configurações do perfil Bash, das configurações do emulador de terminal e do método de copiar e colar comandos. Existem soluções alternativas como você indicou e sugiro que você as use em conjunto com scripts para evitar o problema. Também estou incluindo um link para uma xterm manpage para que você possa ver se há outras configurações ou opções você pode mudar.

Por favor, comente se você tiver dúvidas ou problemas com esta resposta. Eu aprecio o feedback para corrigir quaisquer equívocos e melhorar minhas postagens. Eu posso atualizar minha resposta conforme necessário.

Melhor da Sorte!

    
por 19.06.2018 / 16:38