O prompt do terminal não está acondicionado corretamente

156

Eu tenho um problema onde se eu digitar comandos muito longos no bash o terminal não irá processar o que estou digitando corretamente. Eu esperaria que se eu tivesse um comando como o seguinte:

username@someserver ~/somepath $ ssh -i /path/to/private/key
[email protected]

O comando deve renderizar em duas linhas. Em vez disso, ele geralmente fica por dentro e começa a escrever por cima do meu prompt, assim:

[email protected] -i /path/to/private/key

Se eu decidir voltar e mudar algum argumento, não sei onde o cursor irá aparecer, algumas vezes no meio do prompt, mas geralmente na linha acima onde estou digitando.

Diversão adicional acontece quando eu Subimos para um comando anterior. Eu tentei isso em gnome-terminal e terminator e em i3 e canela. Alguém sugeriu que era o meu prompt, então aqui está:

\[3[01;32m\]\u:\[3[01;34m\] \W3[01;34m \$\[3[00m\]
Ctrl l , reset e clear fazem o que dizem, mas quando eu digito o comando de volta em ou Up as mesmas coisas acontecem.

Eu verifiquei e checkwinsize está ativado no bash. Isso acontece em 80x24 e outros tamanhos de janela.

Isso é algo que eu aprendo a viver? Existe algum pedaço de magia que eu deveria saber? Eu decidi usar apenas um prompt muito curto, mas isso não resolve o problema.

    
por Muricula 19.12.2013 / 23:39

7 respostas

174

Sequências não imprimíveis devem ser entre \[ e \] . Olhando para o seu PS1 , ele tem uma sequência não fechada após \W . Mas, a segunda entrada é redundante, assim como repete a declaração anterior "1; 34" .

\[3[01;32m\]\u:\[3[01;34m\] \W3[01;34m \$\[3[00m\]
                  |_____________|               |_|
                         |                       |
                         +--- Let this apply to this as well.

Como tal, deveria ter a intenção de colorir:

\[3[1;32m\]\u:\[3[1;34m\] \W \$\[3[0m\]
                               |_____|
                                  |
                                  +---- Bold blue.

Manter o "original" também deve funcionar:

\[3[1;32m\]\u:\[3[1;34m\] \W\[3[1;34m\] \$\[3[0m\]
                                  |_|         |_|
                                   |           |
                                   +-----------+-- Enclose in \[ \]

Editar:

A razão para o comportamento é porque bash acredita que o prompt é mais longo do que realmente é. Como um exemplo simples, se um usar:

PS1="3[0;34m$"
       1 2345678

Acredita-se que o prompt tenha 8 caracteres e não 1. Como tal, se a janela do terminal tiver 20 colunas, depois de digitar 12 caracteres, acredita-se que sejam 20 e envolvam o texto. Isso também é evidente se alguém tentar fazer backspace ou Ctrl + u . Para na coluna 9.

No entanto, ela também não inicia uma nova linha, a menos que uma esteja na última coluna. Como resultado, a primeira linha é sobrescrita.

Se continuar digitando, a linha deve passar para a próxima linha após 32 caracteres.

    
por 20.12.2013 / 02:55
79

É principalmente a ver com o tamanho da janela assumida pelo terminal não é o mesmo que o tamanho da janela real. Se você está usando bash, você pode tentar isso.

$ shopt checkwinsize

Se você não conseguir

checkwinsize    on

Em seguida, ative-o com

$ shopt -s checkwinsize

Depois é só tentar executar outro comando (como ls ) ou redimensionar a janela uma vez, o que está acima funciona para mim todas as vezes.

Para sistemas Redhat, em particular, o problema geralmente é causado pela configuração incorreta de ~/.bashrc para não chamar /etc/bashrc . Normalmente, o bash carrega ~/.bashrc , que deve chamar /etc/bashrc , que por padrão contém shopt -s checkwinsize .

    
por 14.11.2014 / 07:34
9

Como mencionado em outras respostas, sequências não imprimíveis, como \e[0;30m , devem ser agrupadas com \[...\] .

Além disso (e o que eu não vejo mencionado ainda) é que \r\n deve estar fora do \[...\] se você tiver um prompt de várias linhas. Demorei um pouco de tentativa e erro para finalmente descobrir isso.

    
por 19.02.2017 / 11:52
6

Isso parece um problema com seu COLUMNS & LINES configurações da variável de ambiente. Quando você redimensiona a janela, eles são tipicamente configurados automaticamente pelo gnome-terminal (eu acredito), você pode forçá-los a serem configurados manualmente, emitindo o comando resize .

Exemplo

Se eu redimensionar meu terminal gnome para 79x17, minhas variáveis aparecem assim:

$ echo $COLUMNS; echo $LINES
79
17

Eu posso forçar assim:

$ resize
COLUMNS=79;
LINES=17;
export COLUMNS LINES;
    
por 19.12.2013 / 23:51
6

Uma vez eu li em algum lugar (não sei mais onde) que usar \[21 e \] em vez de %code% e %code% pode resolver esse problema. Isso fez por mim.

A propósito, definir o PS1 não precisa ser feio.

green="
green="%pre%1$(tput setaf 2)%pre%2"
blue="%pre%1$(tput setaf 4)%pre%2"
dim="%pre%1$(tput dim)%pre%2"
reset="%pre%1$(tput sgr0)%pre%2"

PS1="$dim[\t] " # [hh:mm:ss]
PS1+="$green\u@\h" # user@host
PS1+="$blue\w\$$reset " # workingdir$

export PS1
unset green blue dim reset
1$(tput setaf 2)%pre%2" blue="%pre%1$(tput setaf 4)%pre%2" dim="%pre%1$(tput dim)%pre%2" reset="%pre%1$(tput sgr0)%pre%2" PS1="$dim[\t] " # [hh:mm:ss] PS1+="$green\u@\h" # user@host PS1+="$blue\w\$$reset " # workingdir$ export PS1 unset green blue dim reset
    
por 02.06.2018 / 21:06
5

Para evitar o agrupamento, você também pode aumentar o número de colunas usando, por exemplo,

stty columns 120
    
por 14.09.2016 / 02:38
1

Além disso, o mesmo problema pode ser causado pelo uso de símbolos unicode amplos (como o link ). Este é o snippet que causa o problema (lembre-se de que $Green e $Red são strings de cor com escape adequado):

FancyX='247'
Checkmark='243'


# Add a bright white exit status for the last command
PS1="$White\$? "
# If it was successful, print a green check mark. Otherwise, print
# a red X.
if [[ $Last_Command == 0 ]]; then
    PS1+="$Green$Checkmark "
else
    PS1+="$Red$FancyX "
fi

O Bash não pode calcular o comprimento corretamente, por isso o modo mais fácil seria escapar de 2 de três partes desses símbolos amplos.

FancyX='\[24\]7'
Checkmark='\[24\]3'
    
por 14.09.2018 / 11:18