El siguiente código describe mejor la situación. ¿Por qué la última línea no emite el carácter de línea nueva final? La salida de cada línea se muestra en el comentario. Estoy usando GNU bash, versión 4.1.5
echo -n $'a\nb\n' | xxd -p # 610a620a
x=$'a\nb\n' ; echo -n "$x" | xxd -p # 610a620a
echo -ne "a\nb\n" | xxd -p # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # 610a62
tmp=$(somecommand; echo a); tmp=${tmp%a}
tmp=$(somecommand; echo a)
... Esto ciertamente ha llevado el punto a casa ... Hasta que vi el ejemplo, mi tendencia todavía habría sido usarecho -n a
... ¡pero, por supuesto !, no hay necesidad de el-n
, porque la sustitución de comandos eliminará la nueva línea final introducida en cualquier caso. ... gracias ...Respuestas:
La función de sustitución de comandos
$()
(y su primo el backtick) elimina específicamente las nuevas líneas finales. Este es el comportamiento documentado , y siempre debe tenerlo en cuenta al usar la construcción.El operador de sustitución no elimina las líneas nuevas dentro del cuerpo del texto, pero también se pueden eliminar al dividir las palabras en el shell, por lo que el resultado depende de si usó comillas o no. Tenga en cuenta la diferencia entre estos dos usos:
En el segundo ejemplo, la salida no fue citada y la nueva línea se interpretó como una división de palabras, ¡haciendo que aparezca en la salida como un espacio!
fuente
Cuando se usa la sustitución de comandos, el shell ejecuta los comandos en un subshell, devolviendo su stdout. en este proceso, los caracteres IFS pierden su importancia (si no se citan), ya que el comando devuelve palabras divididas simples, por lo que se eliminan las últimas. Por ejemplo:
y más prácticamente,
pwd
funcionará incluso si el nombre de su directorio tiene una nueva línea en el medio, pero$(pwd)
no lo hará.La solución habitual es agregar algo al final de su comando y luego quitarlo.
fuente
echo "$(echo -e '\n')" | wc
, el que sale1 0 1
, en comparación con el2 0 2
$(pwd)
y"$(pwd)"
, vea la respuesta de Caleb.