Por que esse prompt do bash às vezes mantém parte dos comandos anteriores ao rolar o histórico?

29

Meu prompt do bash, que eu admito ter roubado de alguns lugares e misturado, às vezes adiciona parte dos comandos anteriores ao seu comprimento ao rolar o histórico do bash com as setas para cima / para baixo.

Por exemplo, se meus comandos anteriores fossem:

ls
cd /home/caleb
vim .bashrc

Quando eu estava no meu prompt e rolava a página para cima duas vezes, parecia:

$ vim .bcd / home / caleb

Onde ficam os cinco primeiros caracteres do último comando.

Alguém tem alguma idéia de por que isso está acontecendo e como pode ser interrompido?

Meu prompt é definido com este código (muito tempo para incluir aqui): https://gist.github.com/1679352

Caleb Thompson
fonte
1
Defina PS1 como um valor sem toda a porcaria do vcs e veja o que acontece. Esse é o meu palpite.
Daniel Beck
Você já encontrou o culpado no seu prompt? Estou tendo o mesmo problema.
Acme
Sim, o bash perde em cores e não consegue separar o comprimento das seqüências de caracteres com as cores escapadas do comprimento da sequência visível. Era para isso que o SiegeX estava chegando. Acabei mudando para ZSH e usando um prompt diferente. O ZSH não tem o mesmo problema.
Caleb Thompson
1
Ambas as respostas anteriores não resolveram o meu problema e não deram nenhuma explicação para isso. Verifique se o prompt Custom Bash está sobrescrevendo a si próprio , se alguém tiver pesquisado até este ponto.
D3Hunter
Problema relacionado unix.stackexchange.com/questions/105958/…
matthiasbe

Respostas:

6

Em algum lugar seu prompt é fubar. O que geralmente acontece é que o seu shell pensa que está produzindo códigos de termos não imprimíveis e espera que ocupe espaço. O melhor conselho que posso lhe dar é adicionar sistematicamente (ou remover) seu prompt até que esse comportamento pare para isolar o código que está causando esse problema.

SiegeX
fonte
37

Os códigos de cores precisam estar entre colchetes. Os colchetes informam ao bash que o texto em anexo não deve ser impresso

baseado no exemplo do @ Phreditor, isso mostra que qualquer formatação feita após a nova linha resultará no problema original:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\033[0;90m\$ "

envolver o código de formato em [] garante que o comportamento irritante nunca aconteça:

export PS1="\n\[\[\033[01;33m\][\w]\[\033[00m\]\n\[\033[0;90m\]\$ "

A documentação: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/nonprintingchars.html

Como a formatação PS1 faz com que o valor seja tão longo e difícil de ler, eu coloco os códigos de formato nas variáveis:

BYELLOW='\[\033[01;33m\]'
IBLACK='\[\033[0;90m\]'
PS_CLEAR='\[\033[0m\]'
export PS1="\n${BYELLOW}[\w]${PS_CLEAR}\n${IBLACK}\$ "
m79lkm
fonte
3
Essa deve ser a resposta aceita. Resolveu o problema.
Atcold 26/10/19
1
Deve-se notar (porque não notei;)), que nessa bagunça de barras invertidas e colchetes, os colchetes que seguem a sequência de escape \033NÃO devem ser escapados. Somente os colchetes da embalagem devem ser escapados.
Benjam
Way to confuso para mim lidar com todos esses caracteres especiais, usando o primeiro resultado do Google ajudou a gerar um prompt de trabalho exatamente como eu queria: ezprompt.net
Mallox
Eu queria personalizar minhas cores de prompt por YEARS, mas nunca o fiz desde que sempre tive esse problema! Eu nunca consegui descobrir o porquê, então parei e mantive tudo branco ... Eu estava apenas configurando um computador novo e finalmente me ocorreu realmente pesquisar o problema pela primeira vez ... Tão feliz que sim! Obrigado por esta maravilhosa lição.
TylerH4 13/06
8

Eu tive o mesmo problema e estava relacionado às definições de cores.

No meu caso, tenho um prompt de várias linhas (dá mais espaço para o comando atual, independentemente do comprimento do caminho exibido pelo prompt).

Versão ruim:

export PS1="\n\n\[\033[01;33m[\w]\n\033[00m\$ "

Boa versão:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\$ "

\033[00mtermina a cor. Se for após a nova linha ( \n), evita o redesenho adequado no terminal, substituindo os comandos anteriores pela cor de fundo. Mover para trás da nova linha resolveu o problema.

(usando o Terminal no Mac OS 10.8)

Phreditor
fonte
Isso identificou o problema para mim, enquanto a resposta atual aceita era muito genérica.
Brian
Esta é a resposta mais precisa e deve ser a vencedora (e também foi a solução para o meu problema).
craveytrain
também \nforam os culpados por mim. Obrigado!
Mhulse
3

Na verdade, acho que isso tem a ver com um delimitador ausente de 'caracteres não imprimíveis'. Eu tinha exatamente o mesmo problema, mas movê-lo antes da nova linha (\ n) não o corrigiu. Em vez disso, coloquei corretamente todos os caracteres não imprimíveis (aqui, comandos para colorir) com '\ [' e '\]'.

Ruim (funciona, mas tem o problema de esmagamento de histórico descrito acima):

PS1="\e[32m\u\e[35m@\e[32m\h \e[33m\w\e[36m\n\$\e[0m"

Bom (coloque todos os comandos de cores entre '\ [' e '\]' - não mostra o histórico do comando amassado):

PS1="\[\e[32m\]\u\[\e[35m\]@\[\e[32m\]\h \[\e[33m\]\w\[\e[36m\]\n\$\[\e[0m\]"

i.e. "\e[...m" --becomes--> "\[\e[...m\]"

E se você estiver colocando isso em algo como SecureCRT para enviar automaticamente após o login em um sistema, poderá ser necessário escapar duas vezes de tudo (colocar barras invertidas duplas em todos os lugares) se o sistema de login automático consumir a primeira barra invertida para determinar o caractere a ser enviado :

PS1="\\[\\e[32m\\]\\u\\[\\e[35m\\]@\\[\\e[32m\\]\\h \\[\\e[33m\\]\\w\\[\\e[36m\\]\\n\\$\\[\\e[0m\\]"

i.e. "\..." --becomes--> "\\..."

(Isso é definitivamente verdade para o SecureCRT e pode ser verdade para outras pessoas, como PuTTY ou TeraTerm - testes necessários da sua parte.)

skeetastax
fonte