Bash: como saber se a saída do último comando termina com uma nova linha ou não?

10

Na maioria das vezes, a saída de um comando termina com o caractere de nova linha. Mas, às vezes, não, portanto, o próximo prompt do shell é impresso na mesma linha junto com a saída.

Exemplo:

root @ hostname [~] # echo -n Olá
helloroot @ hostname [~] #

Eu sempre achei isso muito chato.
Agora, eu poderia apenas adicionar um "\ n" no início da variável PS1, mas na maioria das vezes isso imprimirá uma linha extra que eu não preciso.

É possível saber se a saída do último comando terminou com uma nova linha ou não?


Solução:
(Graças a Dennis)

PS1='$(printf "%$((`tput cols`-1))s\r")\u@\h [\w]\$ '
Liberta-te
fonte
Isso deve ser movido para superusuário.
27510 Dech
Eu gosto da sua versão! Você usou $()em um lugar e backticks em outro. Você pode usar $()em ambos.
Pausado até novo aviso.
Eu sei. Mas para mim é mais fácil de ler dessa forma
GetFree
Eu não usaria tput colsporque apenas gera o valor da variável COLUMNS de qualquer maneira, e é mais lento porque não é um shell embutido. Você também deseja incluir \e[K(equivalente a tput el) para excluir o espaço em branco inserido, para que você não tenha muitos espaços em branco à direita ao copiar e colar no caso padrão. Por fim, você precisa incluir toda essa mágica entre \[e \]ou o bash tentará adivinhar a posição do cursor e isso atrapalhará quando você editar seu comando / histórico.
dlitz
1
A coisa toda pode ser feito como apenas:PS1='\[\e[7m%\e[m$( printf "%*s" "$((COLUMNS-1))" "" )\r\e[K\]\u@\h [\w]\$ '
dlitz

Respostas:

6

Eu tenho experimentado o seguinte para emular o recurso do zshBash:

$ unset PROMPT_SP; for ((i = 1; i <= $COLUMNS + 52; i++ )); do PROMPT_SP+=' '; done
$ PS1='\[\e[7m%\e[m\]${PROMPT_SP: -$COLUMNS+1}\015$ '

Emite um sinal de porcentagem de vídeo reverso, seguido de vários espaços para torná-lo agrupado na próxima linha e, em seguida, um retorno de carro, seguido de um sinal de dólar e um espaço. Você pode adicionar escapes de prompt após o "\ 015" para personalizar seu prompt.

A utilização depende de como o seu terminal lida com a quebra da linha de margem direita (margens automáticas). O comprimento de PROMPT_SP é arbitrário, mas deve ser pelo menos 80 ou qualquer que seja a sua largura normal de terminal. Pode ser necessário codificar esse valor se $ COLUMNS ainda não estiver definido no momento em que o forloop for executado ~/.bashrc. Você pode querer shopt -s checkwinsizese ainda não estiver definido.

Pausado até novo aviso.
fonte
Eu me pergunto por que alguém rebaixou cada resposta . Hmmm ... nenhuma explicação. Quão útil.
Pausado até novo aviso.
Aqui está outra maneira, sem usar um loop, para criar a string do pad:printf -v PROMPT_SP '%*s' $((COLUMNS + 52)) ''
Pausada até novo aviso.
O que é um "sinal de porcentagem de vídeo reverso"? A palavra "vídeo" me deixou confusa e não consegui encontrar a resposta no Google.
davidchambers
1
@davidchambers: o plano de fundo do caractere é exibido na cor do primeiro plano e o próprio caractere é exibido na cor do plano de fundo. Veja man 5 terminfoe pesquise "vídeo reverso" para ver alguma documentação que usa essa terminologia.
Pausado até novo aviso.
0

Não, não é possível. O Bash em si não processa ou vê a saída do programa iniciado.

Ocorreu-me que talvez fosse possível escrever um programa para definir PROMPT_COMMAND, que verificasse a posição atual do cursor e emitisse uma nova linha se o cursor não estivesse na borda esquerda.

Urso de pelúcia
fonte
Boa ideia. O único problema é ... é possível saber a posição do cursor?
GetFree
0

zshtenta resolver seu problema. Se a última saída terminar sem uma nova linha, você obterá:

$ echo -n 'abc'
abc%
$ 

Onde os %usos invertidos segundo plano / primeiro plano. Não tenho certeza se é portátil de bashalguma forma.

viraptor
fonte