As questões:
Abra o prompt da linha de comando:
Digite a letra várias vezes:
Em vez de quebrar em uma nova linha, o texto inserido é quebrado na mesma linha:
Agora, comece a pressionar b. Na segunda vez que uma quebra de linha for necessária, ela será quebrada em uma nova linha:
O que causa esse comportamento?
Usar um PS1 como este causa o comportamento:
ps1Color="\033[1;35m"
export PS1='$(echo -en $ps1Color) Baz $'
Observe que o motivo pelo qual desejo usar echo em vez da cor diretamente é porque desejo adicionar a cor condicionalmente com base no status de saída do comando anterior.
Usar a cor diretamente não causa esse comportamento.
Minhas perguntas são:
- Como posso imprimir códigos de cores para uso em um PS1usando eco?
- Se eu quiser deixar meu PS1 com uma cor diferente condicionalmente, qual é a melhor maneira de fazer isso?
- Por que estou vendo esse comportamento?
Atualizar
Para ser claro, eu realmente quero fazer isso usando echo porque quero mudar a corcondicionalmente.
Isso é o que tenho atualmente:
function setPs1Colors_start () {
local previousExit=$?
local ps1Color="\033[1;35m"
local ps1FailBackground="\e[41m"
echo -en $ps1Color
if [[ previousExit -ne 0 ]]
then
echo -en $ps1FailBackground
fi
}
function setPs1Colors_end () {
local ps1DefaultColor="\033[0m"
echo -en $ps1DefaultColor
}
export PS1='$(setPs1Colors_start)[$(date +%b\-%d\ %k:%M)][$(versionControlInfo)\W]\$$(setPs1Colors_end) '
Responder1
\033[1;35m
tem 7 caracteres. bash
não consigo adivinhar que esses 7 caracteres têm na verdade uma largura nula. Caso contrário, pensará que têm 7 colunas de largura.
Ele (ou melhor, readline
o editor de linha subjacente que ele usa) deseja saber qual é a posição atual na tela porque está usando sequências de posicionamento do cursor (para cima, para baixo, para a esquerda, para a direita) para mover o cursor quando você usa teclas de edição.
Então você tem que dizer quais dos caracteres no prompt não movem o cursor. Com bash
, isso é feito usando \[...\]
which informa ao shell que o que está dentro tem largura zero.
Observe também que a expansão do prompt bash
é reconhecida \e
como um caractere ESC, portanto você não precisa usar echo -e
. Você pode simplesmente fazer:
PS1='\[\e[1;35m\] blah $ '
Se você tiver que usar echo
, ou melhor printf
, você faria:
PS1='\[$(if ...; then printf "$color1"; fi)\] blah $ '
Ou:
PS1='$(if ...; then printf "\[$color1\]"; fi) blah $ '
Em zsh
, o equivalente a bash
's \[...\]
é %{...%}
como em tcsh
, mas zsh
tem diretivas para alterar os atributos dos caracteres, então você prefere fazer:
PS1='%B%F{magenta}blah $ '
Para primeiro plano em negrito-magenta. Ele também possui algumas formas de testes condicionais, incluindo on $?
, portanto, seu red
erro if, verde caso contrário pode ser escrito:
PS1='%F{%(?:green:red%)}blah%f $ '
tcsh
tem %B
, mas não %F{color}
. Então, você usaria:
set prompt = '%{\e[1;35m%}blah $ '
Em ksh88
ou pdksh
, você faria:
PS1=$(printf '\5\r\5\33[1;35m\5blah $ ')
Isso define um caractere (aqui 0x5) como oescaparpersonagem. Então, ao colocar texto entre um par deles, você está dizendo ao shell que ele não está visível. Você pode usar qualquer caractere diferente de 0x5, mas ele não deve ocorrer de outra forma em seu prompt e, exceto em mksh, deve ser ignorado pelo terminal porque o shell realmente o grava (junto com o caractere CR).
ksh93
usa apenas uma sequência de posicionamento do cursor: BS
(que move o cursor uma coluna para a esquerda). Para mover para a direita, basta redesenhar os mesmos caracteres. Portanto, não é necessário saber a posição do cursor, apenas a largura de cada caractere digitado. Isso funciona desde que o terminal se enrole sozinho na margem (portanto, não funcionará corretamente com esteterminator
por exemplo). Um efeito colateral se você receber um prompt com sequências de controle é que suas paradas de tabulação não ficarão alinhadas corretamente.