Lidando com comandos de quebra de bash de um certo tamanho

3

Considere que você deseja executar este comando em bash :

echo -n "Command of a specific length will break at the second run attempt."

Aqui está a saída para um TTY 24x80:

ubuntu@ubuntu:~$ echo -n "Command of a specific length will break at the second 
run attempt."
Command of a specific lenght will break at the second run attempt.ubuntu@ubuntu:
~$ 

Considere que você deseja executar o mesmo comando novamente.

Assim que você acertar :

ubuntu@ubuntu:~$ echo -n "Command of a specific lenght will break at the second
run attempt."
Command of a specific lenght will break at the second run attempt.ubuntu@ubuntu:
run attempt."ommand of a specific lenght will break at the second r

Isso acontece com comandos de um determinado tamanho que não imprimem uma nova linha no final.

Isso é extremamente irritante. Até agora não encontrei nenhuma solução para isso, e acho que todos que estão enfrentando esse problema seriam realmente gratos a alguém que tenha uma solução para isso.

    
por kos 25.06.2015 / 14:27

3 respostas

2

Isso pode ser feito com bash também. O truque é usar um PROMPT_COMMAND personalizado que consulte o terminal para a posição do cursor (conforme esta questão ).

Esta solução provavelmente pode ser estendida para outros shells, mas eu estou familiarizado apenas com bash . (Veja a resposta do @muru para uma solução zsh ). E talvez já exista uma opção em bash para fazer isso automaticamente.

Coloque isso no seu .bashrc :

function new.line.if.not.on.left {
    local foo
    local garbage
    local column
    echo -n -e "3[6n"     # as the terminal for the position
    read -s -d \[ garbage    # ignore the first part of the response
    read -s -d R foo         # store the position in foo
    column="$(echo "$foo" | cut -d';' -f2)"    # skip over the row number
    test "$column" "!=" 1 && { tput smso; echo "%"; tput rmso; }
}

PROMPT_COMMAND="new.line.if.not.on.left; $PROMPT_COMMAND"

A última linha envia uma chamada para new.line.if.not.on.left para o seu PROMPT_COMMAND (como você já pode ter um PROMPT_COMMAND definido).

A função bash new.line.if.not.on.left funciona da seguinte forma:

  • echo -n -e "3[6n" é uma peça mágica que pergunta ao terminal sobre a linha e coluna da posição atual do cursor. O terminal "responde" enviando uma entrada de teclado falsa com a resposta.
  • %código%. A primeira parte da resposta é uma algaravia, algum tipo de código de escape. Ignore-o armazenando-o em read -s -d \[ garbage .
  • garbage . Armazene a resposta falsa do teclado na variável bash read -s -d R foo . O foo é necessário para impedir que -s ecoe a entrada na tela novamente. E read é o delimitador - a entrada falsa é terminada por um -d R , não por uma nova linha, como você poderia esperar.
  • R extrai o número da coluna da resposta (ou seja, ignorando o número da linha) e armazena o resultado em column="$(echo "$foo" | cut -d';' -f2)"
  • column Se o número da coluna atual não for 1, imprima o sinal de porcentagem (e uma nova linha). Os comandos test "$column" "!=" 1 && { tput smso; echo "%"; tput rmso; } ativam o "modo de destaque" - o que deve fazer com que o tput se destaque mais - talvez em negrito ou talvez invertendo as cores do plano de fundo e do primeiro plano.
por Aaron McDaid 26.06.2015 / 11:32
4

Use um shell mais inteligente, como zsh :

Observe como ele adicionou um % para indicar a falta de uma nova linha e imprimiu o prompt em uma linha diferente.

    
por muru 25.06.2015 / 14:42
3

Basta pressionar Ctrl L . Isso irá redesenhar o seu terminal e fazer tudo parecer como deveria:

    
por terdon 25.06.2015 / 14:33