Já mudei meu formato de saída do bash para algo assim:
com o qual estou muito feliz. Consegui isso adicionando este código ao .bashrc
:
set_PS1()
{
local RESET=$(tput sgr0 )
local BOLD=$(tput bold )
local RED=$(tput setaf 1 )
local GREEN=$(tput setaf 2 )
local YELLOW=$(tput setaf 3 )
local BLUE=$(tput setaf 4 )
local CYAN=$(tput setaf 6 )
local WHOAMI='\u'
local WHERE='\w'
local HOSTNAME='\h'
local TIME='\D{%H:%M:%S}'
exit_code_prompt() {
local EXIT_CODE=$?
local RED=$(tput setaf 1 )
local GREEN=$(tput setaf 2 )
if [ $EXIT_CODE -ne 0 ]; then
echo -e "$RED$BOLD\xE2\x9C\x98 $EXIT_CODE \xE2\x86\x92" # Red cross mark symbol
else
echo -e "$GREEN$BOLD\xE2\x9C\x93 \xE2\x86\x92" # Green checkmark symbol
fi
}
local LINE_1="$BOLD$YELLOW$TIME $CYAN$WHOAMI$BLUE@$CYAN$HOSTNAME$RESET$BOLD":" $BLUE$WHERE$RESET"
local LINE_2="$BOLD\$(exit_code_prompt) "$RESET$BOLD' \$: '$RESET
PS1="$LINE_1\n$LINE_2"
unset -f set_PS1
}
set_PS1
Meu problema era que se eu tivesse um comando com mais de uma linha, ele não fazia uma quebra de linha, mas sobrescrevia o conteúdo da mesma linha (apenas na representação visual ofc):
Agora, quando eu excluo o comando completo, ele também exclui uma parte do prompt do bash:
Isso poderia ser resolvido adicionando \[
e \]
:
local LINE_1="\[$BOLD$YELLOW$TIME $CYAN$WHOAMI$BLUE@$CYAN$HOSTNAME$RESET$BOLD":" $BLUE$WHERE$RESET\]"
local LINE_2="\[$BOLD\$(exit_code_prompt) "$RESET$BOLD' \$: \]'$RESET
Outro problema persiste. Quando percorro os últimos comandos usados, ele exclui o sinal de prompt $
:
como faço para resolver esse problema?
Já pensei em usar zsh
mas não queria perder bash
funcionalidades como atalhos de teclado com os quais já me acostumei...
ATUALIZAÇÃO: abaixo está meu código atualizado, que ainda não funciona:
set_PS1()
{
local Reset="\\[$(tput sgr0 )\\]"
local Bold="\\[$(tput bold )\\]"
local Red="\\[$(tput setaf 1 )\\]"
local Green="\\[$(tput setaf 2 )\\]"
local Yellow="\\[$(tput setaf 3 )\\]"
local Blue="\\[$(tput setaf 4 )\\]"
local MagentaBG="\\[$(tput setab 5 )\\]"
local Cyan="\\[$(tput setaf 6 )\\]"
local Whoami='\u'
local Where='\w'
local Hostname='\h'
local Time='\D{%H:%M:%S}'
local Exit_Code="$?"
exit_code_prompt() {
local Exit_Code="$?"
local Red="$(tput setaf 1 )"
local Green="$(tput setaf 2 )"
if [ $Exit_Code -ne 0 ]; then
printf "$Red\xE2\x9C\x98 $Exit_Code \xE2\x86\x92 " # Red cross mark symbol
else
printf "$Green\xE2\x9C\x93 \xE2\x86\x92 " # Green checkmark symbol
fi
}
local Line_1="$Bold$Yellow$Time $Cyan$Whoami$Blue@$Cyan$Hostname$Reset$Bold":" $Blue$Where$Reset"
local Line_2="$Bold\$(exit_code_prompt)$Reset$Bold \$: $Reset"
PS1="$Line_1\n$Line_2"
unset -f set_PS1
}
set_PS1
Terei o mesmo problema de antes. O texto com mais de uma linha aparecerá no início da mesma linha e será substituído. Percorrer os comandos resulta na exclusão de uma parte do prompt ou em um bug visual que mostra parte de um comando anterior que não está acessível.
ATUALIZAÇÃO 2 : O problema definitivamente está na exit_code_prompt
função. quando eu o excluo de $Line_2
tudo, funciona conforme o esperado.
Seguindo o conselho de @Daniel, use
E semelhante com todos os outros códigos de cores.
De 6.9 Controlando o prompt no manual:
Voltando à sua pergunta:
Isso ocorre porque sem o
\[
e\]
para agrupar as sequências de controle, o bash não pode calcular corretamente o comprimento do seu prompt.