Bash prompt - backspace apaga o texto alinhado à direita (possível parar?)

2

Eu tenho um problema muito chato. Eu segui todo o protocolo para fazer um bash PS1. Sei que cerca de caracteres não imprimíveis com \[ e \] ou v87%21 e :( ; no entanto, tenho um problema com o texto que vem após onde está o cursor. Quando você pressiona o backspace, tudo desaparece.

Dê uma olhada no bash PS1 (tornando-o seu bashrc e testando pode ser útil - não se esqueça de salvar uma cópia do YOUR bashrc):

## GRML
# grml battery?
GRML_DISPLAY_BATTERY=1

# battery dir
if [ -d /sys/class/power_supply/BAT0 ]; then
    _PS1_bat_dir='BAT0';
else
    _PS1_bat_dir='BAT1';
fi

# ps1 return and battery
_PS1_ret(){
    # should be at beg of line (otherwise more complex stuff needed)
    RET=$?;

    # battery
    if [[ "$GRML_DISPLAY_BATTERY" == "1" ]]; then
        if [ -d /sys/class/power_supply/$_PS1_bat_dir ]; then
            # linux
            STATUS="$( cat /sys/class/power_supply/$_PS1_bat_dir/status )";
            if [ "$STATUS" = "Discharging" ]; then
                bat=$( printf ' v%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Charging" ]; then
                bat=$( printf ' ^%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Full" ] || [ "$STATUS" = "Unknown" ] && [ "$(cat /sys/class/power_supply/$_PS1_bat_dir/capacity)" -gt "98" ]; then
                bat=$( printf ' =%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            else
                bat=$( printf ' ?%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            fi;
        fi
    fi

    if [[ "$RET" -ne "0" ]]; then
        printf '
user@host ~ % █                                                             v87%
1%*s%s\r%s
130 user@host ~ % █                                                       :( v87%
2%s ' "$(tput cols)" ":( $bat " "[0;31;1m" "$RET" else printf '
130 user@host ~ % █                                                            :(
1%*s%s\r
## GRML
# grml battery?
GRML_DISPLAY_BATTERY=1

# battery dir
if [ -d /sys/class/power_supply/BAT0 ]; then
    _PS1_bat_dir='BAT0';
else
    _PS1_bat_dir='BAT1';
fi

# ps1 return and battery
_PS1_ret(){
    # should be at beg of line (otherwise more complex stuff needed)
    RET=$?;

    # battery
    if [[ "$GRML_DISPLAY_BATTERY" == "1" ]]; then
        if [ -d /sys/class/power_supply/$_PS1_bat_dir ]; then
            # linux
            STATUS="$( cat /sys/class/power_supply/$_PS1_bat_dir/status )";
            if [ "$STATUS" = "Discharging" ]; then
                bat=$( printf ' v%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Charging" ]; then
                bat=$( printf ' ^%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Full" ] || [ "$STATUS" = "Unknown" ] && [ "$(cat /sys/class/power_supply/$_PS1_bat_dir/capacity)" -gt "98" ]; then
                bat=$( printf ' =%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            else
                bat=$( printf ' ?%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            fi;
        fi
    fi

    if [[ "$RET" -ne "0" ]]; then
        printf '
user@host ~ % █                                                             v87%
1%*s%s\r%s
130 user@host ~ % █                                                       :( v87%
2%s ' "$(tput cols)" ":( $bat " "[0;31;1m" "$RET" else printf '
130 user@host ~ % █                                                            :(
1%*s%s\r%pre%2' "$(tput cols)" "$bat " fi; } # ps1 git branch _PS1_git(){ if ! type 'git' &> /dev/null; then return 1; fi; if [ ! "$( git rev-parse --is-inside-git-dir 2> /dev/null )" ]; then return 2; fi branch="$( git symbolic-ref --short -q HEAD 2> /dev/null )" if [ "$branch" ]; then printf ' %pre%1%s%pre%2(%pre%1%s%pre%2git%pre%1%s%pre%2)%pre%1%s%pre%2-%pre%1%s%pre%2[%pre%1%s%pre%2%s%pre%1%s%pre%2]%pre%1%s%pre%2' "[0;35m" "[39m" "[35m" "[39m" "[35m" "[32m" "${branch}" "[35m" "[39m" fi; } # grml PS1 string PS1="\[\e[0m\]\$(_PS1_ret)\[\e[34;1m\]${debian_chroot:+($debian_chroot)}\u\[\e[0m\]@\h \[\e[01m\]\w\$(_PS1_git) \[\e[0m\]% "
2' "$(tput cols)" "$bat " fi; } # ps1 git branch _PS1_git(){ if ! type 'git' &> /dev/null; then return 1; fi; if [ ! "$( git rev-parse --is-inside-git-dir 2> /dev/null )" ]; then return 2; fi branch="$( git symbolic-ref --short -q HEAD 2> /dev/null )" if [ "$branch" ]; then printf ' %pre%1%s%pre%2(%pre%1%s%pre%2git%pre%1%s%pre%2)%pre%1%s%pre%2-%pre%1%s%pre%2[%pre%1%s%pre%2%s%pre%1%s%pre%2]%pre%1%s%pre%2' "[0;35m" "[39m" "[35m" "[39m" "[35m" "[32m" "${branch}" "[35m" "[39m" fi; } # grml PS1 string PS1="\[\e[0m\]\$(_PS1_ret)\[\e[34;1m\]${debian_chroot:+($debian_chroot)}\u\[\e[0m\]@\h \[\e[01m\]\w\$(_PS1_git) \[\e[0m\]% "

você deve ver algo como

%pre%

Você pode não ver :( . Isso está ok. Você pode apenas fazer Ctrl c e você verá um código de erro vermelho à esquerda e um %code% na extrema direita.

Então, você verá

%pre%

ou

%pre%

De qualquer forma, há algo à direita do cursor.

Agora, se você digitar algumas coisas e depois Backspace , você verá o %code% (e talvez a informação da bateria) desaparecer! (Pressionar para cima e então para baixo faz o mesmo.)

Se você puder resolver isso, você será meu herói! Provavelmente não é muito fácil, mas se houver alguma solução inteligente ... o chão é seu.

    
por Dylan 09.11.2015 / 03:23

1 resposta

0

Não é uma resposta de programação direta , mas o efeito desejado pode ser conseguido instalando liquidprompt , que pode mostrar $PS1 estatísticas de bateria e muitos outros tipos de dados de diagnóstico úteis. Para ajustar as configurações padrão, basta instalar, executar e editar o ~/.config/liquidpromptrc criado automaticamente.

O programa principal liquidprompt_activate e os scripts que ele chama estão todos em script de shell , o que o torna uma excelente fonte para estudar como ele faz o que faz.

    
por 14.12.2017 / 23:57

Tags

Parêntese na expr aritmética: 3 * (2 + 1) ______ qstntxt ___

%code% parece não gostar de parênteses (usado em matemática para especificar a prioridade do operador):

%pre%

Como expressar a prioridade do operador no bash?

    
______ azszpr149832 ___

Outra maneira de usar %code% bash builtin:

%pre%

Nota

Como @ Stéphane Chazelas apontou , em %code% você deve usar %code% para fazer aritmética %code% ou %code% para legibilidade.

Para portabilidade, use %code% como @Bernhard answer .

    
______ azszpr149830 ___

Você pode usar a expansão aritmética.

%pre%

Na minha opinião pessoal, isso parece um pouco melhor do que usar %code% .

De %code%

%bl0ck_qu0te%     
______ azszpr149916 ___

Não há razão para usar %code% para aritmética em shells modernos.

POSIX define o operador de expansão %code% . Então você pode usar isso em todos os shells compatíveis com POSIX (o %code% de todos os Unix-gostos modernos, traço, bash, yash, mksh, zsh, fino, ksh ...).

%pre%

%code% também introduziu um %code% builtin que é transmitido com o mesmo tipo de expressão aritmética, não expande para algo, mas retorna um status de saída com base em se a expressão é resolvida como 0 ou não, como em %code% :

%pre%

No entanto, como a cotação a torna inábil e não muito legível (não na mesma proporção que %code% , é claro), %code% também introduziu uma forma alternativa %code% :

%pre%

, que é muito mais legível e deve ser usado em seu lugar.

%code% e %code% só estão disponíveis em %code% , %code% e %code% . A sintaxe %code% deve ser preferida se a portabilidade para outros shells for necessária, %code% é necessário apenas para shells pré-POSIX semelhantes a Bourne (normalmente o shell Bourne ou versões antigas do shell Almquist).

Na frente não-Bourne, existem alguns shells com operador aritmético integrado:

  • %code% / %code% (na verdade, o primeiro shell Unix com avaliação aritmética incorporada):

    %pre%
  • %code% (com base em %code% )

    %pre%
  • como uma nota de história, a versão original do shell Almquist, como publicado no usenet em 1989, tinha um %code% construído (na verdade, mesclado com %code% ), mas foi removido posteriormente.

______ azszpr149991 ___

%code% é um comando externo, não é uma sintaxe especial do shell. Portanto, se você quiser que %code% veja os caracteres especiais do shell, será necessário protegê-los da análise do shell, citando-os. Além disso, %code% precisa que cada número e operador sejam passados como um parâmetro separado. Assim:

%pre%

A menos que você esteja trabalhando em um antigo sistema unix dos anos 1970 ou 1980, há muito poucas razões para usar %code% . Antigamente, os shells não tinham uma maneira interna de realizar aritmética, e você precisava chamar o utilitário %code% . Todos os shells POSIX possuem aritmética interna por meio da sintaxe expansão aritmética .

%pre%

A construção %code% se expande para o resultado da expressão aritmética (escrita em decimal). Bash, como a maioria das shells, suporta apenas módulos aritméticos inteiros 2 64 (ou módulo 2 32 para versões mais antigas do bash e algumas outras shells em máquinas de 32 bits). p>

O Bash oferece uma sintaxe de conveniência adicional quando você deseja realizar atribuições ou para testar se uma expressão é 0, mas não se importa com o resultado. Esta construção também existe em ksh e zsh, mas não em sh simples.

%pre%

Além da aritmética inteira, %code% oferece algumas funções de manipulação de string. Eles também são incluídos pelos recursos de shells POSIX, exceto por um: %code% testa se a string corresponde ao regexp especificado. Um shell POSIX não pode fazer isso sem ferramentas externas, mas o bash pode com %code% (com um sintaxe diferente de regexp - %code% é uma ferramenta clássica e usa BRE, bash usa ERE).

A menos que você esteja mantendo scripts executados em sistemas de 20 anos, não é necessário saber que %code% já existiu. Use aritmética de shell.

    
______ azszpr149824 ___

Use parênteses com aspas:

%pre%

As citações evitam que o bash interprete os parênteses como a sintaxe bash.

    
______ azszpr349827 ___

Se você tiver bc ...

%pre%     
___ Como manter um log sobre quando a tela foi bloqueada / desbloqueada