Como usar a quebra de linha no comando read -p ao usar variáveis ​​na string de prompt

Como usar a quebra de linha no comando read -p ao usar variáveis ​​na string de prompt

Quero uma quebra de linha após o prompt ao usar a função cowsay no prompt:

read -p "$(cowsay "do you know this word?") \n" answer

existem várias respostas para este problema:

1)https://stackoverflow.com/questions/4296108/how-do-i-add-a-line-break-for-read-command/4296147

2)https://stackoverflow.com/questions/12741529/how-to-break-a-line-add-a-newline-in-read-p-in-bash

Porém as respostas usam a ''notação, o que não resolve o cowsaycomando

Responder1

Por que você usaria a -popção para a qual precisa do bashshell?

Apenas faça:

cowsay "do you know this word?"
read answer

Em bash, a -popção só é útil em conjunto com -e(outra bashextensão que faz com que basho 's readse comporte como zsh' vared) onde bashpode ser necessário redesenhar o prompt em algumas ocasiões (como em Ctrl+L). Mas então, você provavelmente não precisaria nem desejaria redesenhar esse prompt quando ele tiver várias linhas.

Se você quisesse, você sempre poderia fazer:

read -ep "$(cowsay "do you know this word?")"$'\n' answer

(aqui usando $'...'a forma de cotação do ksh93 que entende sequências de escape do tipo C)

ou

read -ep "$(cowsay "do you know this word?")
" answer

De forma mais geral, o problema é que a substituição do comando remove os caracteres de nova linha (não apenas um, todos eles que podem ser considerados um bug/má funcionalidade¹) do final da saída do comando.

Para contornar isso, o truque usual é fazer:

output=$(cowsay "do you know this word?"; echo .)
output=${output%.}
read -p "$output" answer

Ou seja, adicione .\nà saída. A substituição do comando remove o \ne removemos o .deixando ${output%.}toda a saída do comando (desde que não contenha caracteres NUL em shells diferentes de zsh, e que seja um texto válido no código do idioma atual em yash).

Para constar, em outros shells do tipo Korn, a sintaxe para reademitir um prompt por si só é:

read 'answer?prompt: '

O shell Korn também redesenharia esse prompt ao ler no terminal e uma opção de editor fosse habilitada (como com set -o emacsou set -o vi). zshtambém suporta essa sintaxe para compatibilidade, mas o editor de linha é usado apenas para vared, não para readlá.


¹ por exemplo, torna as coisas basename=$(basename -- "$file")erradas, pois pode retirar caracteres de nova linha do final do nome do arquivo, não apenas aquele adicionado porbasename

informação relacionada