web-development-kb-pt.site

Exibir coisas abaixo do prompt em um prompt de shell?

Vamos dizer que meu prompt parece assim (o _ representa meu cursor)

~ % _

Existe alguma maneira que eu poderia fazer parecer assim

~ % _
[some status]

A questão foi originalmente sobre ZSH, mas agora tem outras respostas.

21
xenoterracide

As configurações a seguir parecem funcionar. O texto na segunda linha desaparece se a linha de comando transbordar a primeira linha. A função preexec apaga a segunda linha antes de executar o comando; Se você quiser mantê-lo, altere para preexec () { echo; }.

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]
PS1_2='[some status]'
PS1="%{$terminfo_down_sc$PS1_2$terminfo[rc]%}%~ %# "
preexec () { print -rn -- $terminfo[el]; }

% As fugas são documentadas no manual ZSH (man zshmisc).

Terminfo é uma API de acesso terminal. ZSH tem um módulo terminfo que fornece acesso ao banco de dados de descrição do terminal: $terminfo[$cap] É a seqüência de caracteres para enviar para exercer o recurso do terminal $cap, Ou seja, para executar sua $cap Comando. Consulte man 5 terminfo (No Linux, o número da seção pode variar em outros unices) para obter mais informações.

A sequência de ações é: mover o cursor para baixo uma linha (cud1), Depois backup (cuu1); Salve a posição do cursor (sc); Mova o cursor para baixo uma linha; Imprimir [some status]; restaurar a posição do cursor. O bit de baixo e para cima no início é necessário apenas no caso do prompt estar na linha inferior da tela. A linha Preexec apaga a segunda linha (el) para que ele não seja misturado com a saída do comando.

Se o texto na segunda linha for mais largo do que o terminal, a exibição pode ser eliminada. Usar Ctrl+.L em uma pitada para reparar.

17

Aqui está um bash equivalente da solução ZSH de Gilles. Bash não tem um módulo Terminfo nativo, mas o comando tput (empacotado com terminfo) faz a mesma coisa.

PS1_line1='\w \$ '
PS1_line2='[some status]'

if (tput cuu1 && tput sc && tput rc && tput el) >/dev/null 2>&1
then
    PS1="
\[$(tput cuu1; tput sc)\]
\[${PS1_line2}$(tput rc)\]${PS1_line1}"
    PS2="\[$(tput el)\]> "
    trap 'tput el' DEBUG
else
    PS1="$PS1_line2 :: $PS1_line1"
fi

Se o terminal não suportar um dos recursos, ele voltará a um prompt de uma linha.

O trap linha é uma maneira hacky para emular a função preexec. Veja https://superuser.com/questions/175799/ para mais informações.

[~ # ~] Editar [~ # ~] : script aprimorado com base nos comentários de Gilles.

5
Jander