Según el siguiente ejemplo, y como en mi pregunta reciente En bash, ¿a dónde se ha ido el char de Newline? , Quiero saber "por qué" sucede
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p
# Output is: 610a62
# The trailing newline from the 'echo' command
# has been "deleted" by Command Substitution
Supongo que debe haber una razón muy importante para que una acción de shell, a saber, la sustitución de comandos, realmente elimine algunos datos de la salida del comando que está sustituyendo ...
pero no puedo entender esto, ya que parece ser la antítesis de lo que se supone que debe hacer ... es decir. volver a pasar la salida de un comando al proceso del script ... Retener un personaje me parece extraño, pero supongo que hay una razón sensata para ello ... Estoy ansioso por descubrir cuál es esa razón ... .
Respuestas:
Porque el shell no estaba destinado originalmente a ser un lenguaje de programación completo.
Es bastante difícil eliminar un final
\n
de alguna salida de comando. Sin embargo, para fines de visualización, casi todos los comandos terminan con su salida\n
, así que ... tiene que haber una forma simple de eliminarlo cuando desea usarlo en otro comando. La eliminación automática con la$()
construcción fue la solución elegida.Entonces, tal vez aceptes esta pregunta como respuesta:
¿Puedes encontrar una manera simple de eliminar el final
\n
si esto no se hizo automáticamente en el siguiente comando?Tenga en cuenta que se requieren comillas para evitar romper los espacios dobles que pueden aparecer en fechas formateadas.
fuente
shopt
que cambiar su comportamiento predeterminado descrito, entonces estaría feliz de nuevo ... Me resulta difícil pensar que Bash / Linux / Unix contaminaría una función tan crítica como "capturar stdout" simplemente porquedate
no tiene una opción con / sin '\ n' ... La solución obvia sería que bash (u otro shell) tiene unshopt
para esto ... ¿Conoces alguno? .. y ¿tiene algún enlace de referencia que hable de por qué y para qué se emite? ... y por qué nodate
tiene una opción \ n ... ¡Debería!$()
sintaxis alternativa preferida .{ echo -n "The current date is "; var="$(date; echo -e x)"; var="${var%x}"; echo -n "$var"; echo ", have a good day!"; }
.. que así sea :)date
funcionaría, pero solo lo usédate
como ejemplo de cualquier comando ...Es parte del estándar :
Por supuesto, el estándar probablemente está escrito de esta manera porque así es como lo
ksh
hizo o algo así, pero es el estándar y es un comportamiento documentado. Si no le gusta, use Perl u otra cosa que le permita mantener las nuevas líneas finales.fuente
Bueno, tiene sentido para mi. La nueva línea solo está allí en primer lugar, en la salida del comando normal, de modo que el mensaje aparece después de que el comando se completa en una nueva línea. La nueva línea no es parte de la salida original en la mayoría de los casos, está ahí para ordenar la pantalla. Cuando analiza el resultado de un comando, la nueva línea al final suele ser problemática. ¿Por qué el
wc
comando genera 2 líneas de texto? Oh, no lo hace, genera uno seguido de una nueva línea. Cuando analizawc
, no quiere preocuparse por el hecho de que hay 2 líneas de salida; en realidad no hay, solo hay una.fuente
\n
lastdout
sustitución del comando elimina un en la secuencia original . es decir. mis datos originales (datos muy importantes) han eliminado las nuevas líneas finales, incluso cuando los datos están envueltos en "comillas". Entiendo razonablemente cómo y por qué funciona la división de palabras, pero no tengo ni idea de por qué la sustitución de comandos elimina solo las nuevas líneas y solo las finales .Me encontraba con el mismo problema, y encontré el siguiente ejemplo. Parece que la cita ayudó a la situación, al menos lo hizo para mí:
http://tldp.org/LDP/abs/html/commandsub.html .
fuente
$str
contiene la cadena"a b c"
. Si pasa$str
aecho
sin comillas (echo $str
),echo
recibiráa
,b
yc
hasta tres argumentos separados. Su shell no se preocupa por el espacio en blanco entre los argumentos.echo
luego imprimirá esos argumentos con espacios que separan cada uno, para que obtenga"a b c"
. Si pasa la variableecho
entre comillas (echo "$str"
), el shell lo ve como un argumento y loecho
recibe como tal, por lo que el espacio en blanco no se contrae. Lo mismo se aplica a las nuevas líneas.-n
bandera,echo
agrega una nueva línea final a su salida, por lo que ambos ecos en su ejemplo tienen nuevas líneas finales. Sin embargo, si intentaecho -n $dir_listing
oecho -n "$dir_listing"
, verá que no se imprime una nueva línea final con o sin comillas$dir_listing
, lo que sugiere que el problema está en la sustitución del comando.¿Por qué
echo "hello "
(sin las comillas) engulle el espacio? el shell ve el valor de los caracteres IFS como delimitadores, por lo que se eliminan los finales (que no delimitan nada). la sustitución de encomiendas es simplemente ejecutar los elogios en un subconjunto, por lo que sigue la misma lógica.fuente
x="hello "
yx="hello "
perderá todos sus espacios a la derecha si el se visualizan a travésecho $x
... Sin embargo , solamente la última línea nueva del Comando Substituton se pierde.IFS
no tiene nada que ver con quitar nuevas líneas al final de las sustituciones de comandos.