Aviso de bash: usando \ [e \] dentro de PROMPT_COMMAND

5

Estou trabalhando em um prompt bash. Também estou tentando criar o prompt de maneira inteligente, para que seja facilmente legível e possa ser mantido. Isso significa não ter um grande export PS1 .

Várias fontes (incluindo esta questão ) fazem referência à necessidade de \[ e \] em torno da formatação, para ajudar o bash sabe não sobrescrever o prompt com comandos longos.

Ao criar a sequência PROMPT_LAST_EXIT_STATUS , a intenção é mostrar o status de saída do último comando ( $? ) em vermelho ou nada (se $? for 0). Isso funciona, mas os% literal [ s e ] s são exibidos no prompt e o longo problema de comando ainda está presente. É provavelmente um problema de escape em algum lugar, mas eu não encontrei.

Ocódigoaseguirestáem~/.bashrc.

prompt_last_exit_status(){PROMPT_LAST_EXIT_STATUS="${?}";
if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]];
then
    PROMPT_LAST_EXIT_STATUS=
else
    PROMPT_LAST_EXIT_STATUS=\[$(tput setaf 1)$(tput bold)\]${PROMPT_LAST_EXIT_STATUS}
    PROMPT_LAST_EXIT_STATUS+=\[$(tput sgr0)\]
    PROMPT_LAST_EXIT_STATUS+=" "
fi;
}


prompt_command () {
    prompt_last_exit_status
}
export PROMPT_COMMAND=prompt_command

PS1="\${PROMPT_LAST_EXIT_STATUS}"
PS1+="\[$(tput setaf 6)$(tput bold)\]\w"
PS1+="\[$(tput sgr0)\] \$ \[$(tput sgr0)\]"
export PS1
    
por David Lord 28.05.2015 / 03:33

2 respostas

3

Suas atribuições para PROMPT_LAST_EXIT_STATUS não estão sendo citadas. Por isso, você não está colocando \[ e \] na sequência. Você está colocando apenas [ e ] (porque \ s estão sendo tratados como caracteres de escape).

Compare:

$ foo=\[hello\]
$ echo "$foo"
[hello]

Vs:

$ foo="\[hello\]"
$ echo "$foo"
\[hello\]

Não apenas isso: expansão de parâmetro (a interpolação de variáveis na cadeia de prompt) ocorre após a expansão de caracteres especiais de prompt. Portanto, colocar o \[ e o \] na variável PROMPT_LAST_EXIT_STATUS não funcionará, já que quando o $PROMPT_LAST_EXIT_STATUS for expandido, o \[ e o \] não serão mais especiais. Uma alternativa de trabalho iria mover a configuração de cor para ser incondicional, algo como:

prompt_last_exit_status () {
    PROMPT_LAST_EXIT_STATUS="${?}"
    if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]]
    then
        PROMPT_LAST_EXIT_STATUS=
    else
        PROMPT_LAST_EXIT_STATUS+=" "
    fi
}

prompt_command () {
    prompt_last_exit_status
}
export PROMPT_COMMAND=prompt_command

PS1="\[$(tput setaf 1)$(tput bold)\]\${PROMPT_LAST_EXIT_STATUS}\[$(tput sgr0)\]"
PS1+="\[$(tput setaf 6)$(tput bold)\]\w"
PS1+="\[$(tput sgr0)\] \$ \[$(tput sgr0)\]"
export PS1
    
por 28.05.2015 / 23:49
0

PS1 avalia \[ e \] como 1 e 2. Se você não quiser colocar \[ e sua coloração no PS1 porque é muito longo, você pode usar variáveis PS1 que já incluem 1 e 2. Uma variável conterá 1 se você usar $'$'print_status2'1' e irá conter 2 se você usar su . Eu modifiquei o seu código para funcionar como está escrito.

prompt_last_exit_status () {
    PROMPT_LAST_EXIT_STATUS=$?
    if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]]; then
        PROMPT_LAST_EXIT_STATUS=
    else
        PROMPT_LAST_EXIT_STATUS=$'
print_status() {
    printf "
prompt_last_exit_status () {
    PROMPT_LAST_EXIT_STATUS=$?
    if [[ ${PROMPT_LAST_EXIT_STATUS} == "0" ]]; then
        PROMPT_LAST_EXIT_STATUS=
    else
        PROMPT_LAST_EXIT_STATUS=$'
print_status() {
    printf "%pre%1$(tput setaf 1)$(tput bold)%pre%2$?%pre%1$(tput sgr0)%pre%2"
}
export -f print_status
export PS1='$(print_status) '
1'$(tput setaf 1)$(tput bold)$'%pre%2'$PROMPT_LAST_EXIT_STATUS PROMPT_LAST_EXIT_STATUS+=$'%pre%1'$(tput sgr0)$'%pre%2' PROMPT_LAST_EXIT_STATUS+=" " fi } prompt_command () { prompt_last_exit_status } export PROMPT_COMMAND=prompt_command PS1='$PROMPT_LAST_EXIT_STATUS' PS1+="\[$(tput setaf 6)$(tput bold)\]\w" PS1+="\[$(tput sgr0)\] \$ \[$(tput sgr0)\]" export PS1
1$(tput setaf 1)$(tput bold)%pre%2$?%pre%1$(tput sgr0)%pre%2" } export -f print_status export PS1='$(print_status) '
1'$(tput setaf 1)$(tput bold)$'%pre%2'$PROMPT_LAST_EXIT_STATUS PROMPT_LAST_EXIT_STATUS+=$'%pre%1'$(tput sgr0)$'%pre%2' PROMPT_LAST_EXIT_STATUS+=" " fi } prompt_command () { prompt_last_exit_status } export PROMPT_COMMAND=prompt_command PS1='$PROMPT_LAST_EXIT_STATUS' PS1+="\[$(tput setaf 6)$(tput bold)\]\w" PS1+="\[$(tput sgr0)\] \$ \[$(tput sgr0)\]" export PS1

Informações extras

Você também pode ter a referência PS1 como uma função que será chamada quando o PS1 for avaliado.

%pre%

NOTA: Exportar a função %code% garantirá que, quando você %code% , PS1 possa referenciar a função da qual depende. Além disso, certifique-se de que qualquer função exportada funcionará com o shell padrão Bourne (sh) como git e vim use esses shells e tentará usar essas funções.

    
por 15.11.2017 / 22:41