Como usar o linebreak no comando read -p enquanto usa variáveis na string de prompt

1

Eu quero ter uma quebra de linha após o prompt enquanto estiver usando a função cowsay no prompt:

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

existem várias respostas para este problema:

1) link

2) link

No entanto, as respostas usam a notação '' , que não resolve o comando cowsay

    
por Grunwalski 25.11.2017 / 13:50

1 resposta

1

Por que você usaria a opção -p para a qual você precisaria do bash shell?

Basta fazer:

cowsay "do you know this word?"
read answer

Em bash , a opção -p só é útil em conjunto com -e (outra extensão bash , que faz com que bash read se comporte como zsh vared ) bash talvez precise redesenhar o prompt em algumas ocasiões (como em Ctrl + L ). Mas, provavelmente, você não precisaria nem desejaria que ele fosse redesenhado quando houver 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 citação de $'...' do ksh93 que entende sequências de escape semelhantes a C)

ou

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

Em geral, o problema é que a substituição de comando remove caracteres de nova linha (não apenas um, todos eles que podem ser considerados um bug / falha de caractere¹) do final da saída do comando.

Para contornar isso, o truque comum é fazer:

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

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

Para o registro, em outros shells semelhantes ao Korn, a sintaxe para read para emitir um prompt por si só é:

read 'answer?prompt: '

O shell Korn também iria redesenhar esse aviso ao ler o terminal e uma opção de editor foi ativada (como com set -o emacs ou set -o vi ). zsh também suporta essa sintaxe para compatibilidade, mas o editor de linha é usado apenas para vared , não para read there.

¹ por exemplo, faz com que coisas como basename=$(basename -- "$file") estejam erradas, já que poderia retirar caracteres de nova linha do final do nome do arquivo, não apenas aquele adicionado por basename

    
por 25.11.2017 / 14:23