echo el carácter de nueva línea no funciona en bash

12

Tengo un script bash que tiene muchas echodeclaraciones y también alias echoa echo -eambas en .bash_profiley .bashrc, por lo que las nuevas líneas se imprimen correctamente para una declaración como echo 'Hello\nWorld'la salida debería ser

Hello
World

pero el resultado que obtengo es

Hello\nWorld

Incluso intenté usarlo shopt -s expand_aliasesen el script, no ayuda

Estoy ejecutando mi script como bash /scripts/scriptnm.sh; si lo ejecuto ya . /scripts/scriptnm.shque obtengo el resultado deseado ...

Bashuser
fuente
3
alias echocomo quieres es una mala práctica en mi humilde opinión
shellholic
1
Use comillas dobles para que el \ n sea interpretado. Las comillas simples impiden la interpretación de \ n y muchas otras cosas.
BillThor

Respuestas:

15

La historia mixta de echosignifica que su operación predeterminada varía de shell a shell. POSIX especifica que el resultado de echoestá "definido por la implementación" si el primer argumento es -no si algún argumento contiene una barra diagonal inversa.

Es más confiable de usar printf(ya sea como un comando incorporado o un comando externo) donde el comportamiento está más bien definido: los escapes de barra invertida de estilo C y los especificadores de formato son compatibles con la cadena de formato (el primer argumento).

printf 'foo\nbar\n'
printf '%s\n%s\n' foo bar

Se puede controlar la expansión de la barra invertida secuencias de escape de fiesta ‘s echocomando integrado con la xpg_echoopción del shell.

Configúrelo en la parte superior de cualquier script bash para echoexpandir automáticamente los escapes de barra invertida sin tener que agregar -ea cada comando echo.

shopt -s xpg_echo
echo 'foo\nbar'
Chris Johnsen
fuente
shopt -s xpg_echo; Trabajó para mi.
Bashuser
6

Cuando lo utiliza bash myfile.sh, Bash se ejecuta en modo "por lotes", en un proceso separado , y no lee su perfil o archivo de registro.

Cuando lo usa . myfile.sh, el proceso de shell actual obtiene el archivo (como si su contenido hubiera sido escrito por usted), por lo tanto, ve sus alias definidos actualmente.

En general, es una muy mala idea escribir scripts que dependen de una configuración de shell particular, especialmente alias, a menos que los defina en el script mismo. ( Nunca confíes en el usuario .bashrc, incluso si es tuyo).

Gravedad
fuente
5

La práctica recomendada es usar printfpara todos los nuevos scripts.

printf '%s\n%s\n' "Hello" "World"

printf '%s\n' "Hello\nWorld"
Dennis Williamson
fuente
+1 printf es un poco más complicado de usar que echo, pero vale más que evitar las inconsistencias de echo.
Gordon Davisson
1

Esto funciona bien en la terminal

#!/bin/bash
alias echo="echo -e"
echo "Hello\nWorld"

guardar en un archivo y hacerlo ejecutable (chmod + x)

ejecutar como ./your_file

LaLeX
fuente
ejecútelo como bash your_file y verifique el resultado.
Bashuser
Funciona como se esperaba
LaLeX
pero echo "Hello \ nWorld" no muestra el resultado esperado. Como echo ya tiene el alias de echo -e debería, pero eso no funciona y esa es mi pregunta
Bashuser
Dado que es una mala práctica alias echo (los programas que dependen de él pueden romperse), debe eliminar el alias y en su búsqueda de script para echo end reemplazarlo por echo -e
LaLeX
Muchas gracias LaLex por sus respuestas, ¿hay alguna manera de que pueda lograr el resultado esperado con el alias, aunque no es una buena práctica
Bashuser