shell – ¿Cómo dividir una cadena larga en varias líneas en el indicador de lectura -p dentro del código fuente?

Pregunta:

Estoy escribiendo un script de instalación que se ejecutará como /bin/sh .

Hay una línea que solicita un archivo:

read -p "goat may try to change directory if cd fails to do so. Would you like to add this feature? [Y|n] " REPLY

Me gustaría dividir esta larga línea en muchas líneas para que ninguna supere los 80 caracteres. Me refiero a las líneas dentro del código fuente del script; ¡no se trata de las líneas que se imprimirán realmente en la pantalla cuando se ejecute el script!

Lo que he probado:

  • Primer enfoque:

     read -p "oat may try to change directory if cd fails to do so. " \ "Would you like to add this feature? [Y|n] " REPLY

    Esto no funciona porque no se imprime. Would you like to add this feature? [Y|n] .

  • Segundo enfoque:

     echo "oat may try to change directory if cd fails to do so. " \ "Would you like to add this feature? [Y|n] " read REPLY

    No funciona tan bien. Imprime una nueva línea después del mensaje. Agregar la opción -n a echo no ayuda: solo imprime:

     -n goat oat may try to change directory if cd fails to do so. Would you like to add this feature? [Y|n] # empty line here
  • Mi solución actual es

     printf '%s %s ' \ "oat may try to change directory if cd fails to do so." \ "Would you like to add this feature? [Y|n] " read REPLY

y me pregunto si hay una mejor manera.

Recuerde que estoy buscando una solución compatible con /bin/sh .

Respuesta:

En primer lugar, desacoplemos la lectura de la línea de texto usando una variable:

text="line-1 line-2"             ### Just an example.
read -p "$text" REPLY

De esta forma el problema se convierte en: Cómo asignar dos líneas a una variable.

Por supuesto, un primer intento de hacer eso es:

a="line-1 \
line-2"

Escrito así, la var a realidad obtiene el valor line-1 line-2 .

Pero no le gusta la falta de sangría que esto crea, bueno, entonces podemos intentar leer las líneas en la var desde un here-doc (tenga en cuenta que las líneas sangradas dentro de here-doc necesitan una tabulación, no espacios, para que funcione correctamente):

    a="$(cat <<-_set_a_variable_
        line-1
        line-2
        _set_a_variable_
    )"
echo "test1 <$a>"

Pero eso fallaría ya que en realidad se escriben dos líneas en $a . Una solución alternativa para obtener solo una línea podría ser:

    a="$( echo $(cat <<-_set_a_variable_
        line 1
        line 2
        _set_a_variable_
        ) )"
echo "test2 <$a>"

Eso está cerca, pero crea otros problemas adicionales.

Solución correcta.

Todos los intentos anteriores solo harán que este problema sea más complejo de lo que debe ser.

Un enfoque muy básico y simple es:

a="line-1"
a="$a line-2"
read -p "$a" REPLY

El código para su ejemplo específico es (para cualquier shell cuya read admita -p ):

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        read -p "$a" REPLY

Para todas las demás conchas, use:

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        printf '%s' "$a"; read REPLY

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım