Cómo usar el salto de línea en el comando read -p mientras se usan variables en la cadena de solicitud

Cómo usar el salto de línea en el comando read -p mientras se usan variables en la cadena de solicitud

Quiero tener un salto de línea después del mensaje mientras uso la función cowsay en el mensaje:

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

Hay múltiples respuestas a 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

Sin embargo, las respuestas usan la ''notación, que no resuelve el cowsaycomando.

Respuesta1

¿Por qué usarías la -popción para la cual necesitarías el bashshell?

Solo haz:

cowsay "do you know this word?"
read answer

En bash, la -popción solo es útil junto con -e(otra bashextensión que hace que bash's readse comporte como zsh's vared) donde bashes posible que sea necesario volver a dibujar el mensaje en algunas ocasiones (como en Ctrl+L). Pero entonces, probablemente no necesite ni quiera volver a dibujar ese mensaje cuando tiene varias líneas.

Si quisieras, siempre podrías hacer:

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

(aquí usando $'...'la forma de cita de ksh93 que entiende secuencias de escape tipo C)

o

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

De manera más general, el problema es que la sustitución de comandos elimina los caracteres de nueva línea (no solo uno, todos los que podrían considerarse un error/mal funcionamiento¹) del final de la salida del comando.

Para solucionar esto, el truco habitual es hacer:

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

Es decir, agregar .\na la salida. La sustitución de comandos elimina el \ny nosotros eliminamos el .dejando ${output%.}la salida completa del comando (siempre que no contenga caracteres NUL en shells distintos a zsh, y que sea texto válido en la configuración regional actual en yash).

Para que conste, en otros shells similares a Korn, la sintaxis para reademitir un mensaje por sí solo es la siguiente:

read 'answer?prompt: '

El shell Korn también volvería a dibujar ese mensaje al leer desde la terminal y se ha habilitado una opción de editor (como con set -o emacso set -o vi). zshtambién admite esa sintaxis por compatibilidad, pero el editor de líneas solo se usa para vared, no para readallí.


¹ por ejemplo, hace que las cosas estén basename=$(basename -- "$file")mal, ya que podría eliminar los caracteres de nueva línea del final del nombre del archivo, no solo el agregado porbasename

información relacionada