Considere las dos muestras de concha
$ ls
myDoc.html
SomeDirectory
someDoc.txt
y
$ echo $(ls)
myDoc.html SomeDirectory someDoc.txt
El primero se ejecuta lsy, según tengo entendido, agrega el contenido del directorio de trabajo actual al stdoutarchivo (que es lo que muestra el terminal). ¿Es esto correcto?
El segundo toma el valor del lscomando (lo que significa que es el contenido del directorio de trabajo actual) y lo imprime en el stdoutarchivo. ¿Es esto correcto?
¿Por qué los dos comandos dan diferentes salidas?

lspor sí solo no le da múltiples artículos por línea?echo *?Respuestas:
Cuando ejecutas este comando:
el terminal muestra la salida de
ls.Cuando ejecutas este comando:
el shell captura la salida
$(ls)y realiza la división de palabras en él. Con el valor predeterminadoIFS, esto significa que todas las secuencias de espacios en blanco, incluidos los caracteres de nueva línea, se reemplazan por un solo espacio en blanco. Es por eso que la salida deecho $(ls)aparece en una línea.Para una discusión avanzada sobre la división de palabras, vea las preguntas frecuentes de Greg .
Suprimir la división de palabras
El shell no realiza la división de palabras en cadenas entre comillas. Por lo tanto, puede suprimir la división de palabras y retener la salida multilínea con:
lsy salida multilíneaEs posible que haya notado que a
lsveces imprime más de un archivo por línea:Este es el valor predeterminado cuando la salida de
lsva a un terminal. Cuando la salida no va directamente a una terminal,lscambia su valor predeterminado a un archivo por línea:Este comportamiento está documentado en
man ls.Otra sutileza: sustitución de comandos y líneas nuevas
$(...)es la sustitución de comandos y el shell elimina los caracteres de línea nueva del resultado de la sustitución de comandos . Esto normalmente no se nota porque, por defecto,echoagrega una nueva línea al final de su salida. Por lo tanto, si pierde una nueva línea desde el final$(...)y gana unaecho, no hay cambio. Sin embargo, si la salida de su comando termina con 2 o más caracteres de nueva línea yechoagrega solo uno, a su salida le faltarán una o más nuevas líneas. Como ejemplo, podemos usarprintfpara generar caracteres de nueva línea finales. Tenga en cuenta que los dos comandos siguientes, a pesar del número diferente de líneas nuevas, producen el mismo resultado de una línea en blanco:Este comportamiento está documentado en
man bash.Otra sorpresa: expansión del nombre de ruta, dos veces
Vamos a crear tres archivos:
Observe la diferencia entre
ls file?yecho $(ls file?):En el caso de
echo $(ls file?)la glob archivofile?se expande en dos ocasiones , haciendo que los nombres de archivofile1yfile2de aparecer dos veces en la salida. Esto se debe a que, como señala Jeffiekins, la expansión del nombre de ruta se realiza primero por el shell antes delsejecutarse y luego nuevamente antes deechoejecutarse.La segunda expansión del nombre de ruta se puede suprimir si usamos comillas dobles:
fuente
isattypuede verificar si stdout es un tty, ls usa esto para determinar si usar colores o no.$( )realidad proporciona una barrera de sintaxis para que no necesite interpolar?$()proporciona una barrera de sintaxis.echocomando expandirá el comodín . Por ejemplo, silsdevuelve el archivo? file1 file2 , entoncesecho $(ls)devolverá el archivo? archivo1 archivo2 archivo1 archivo2 .echono expande comodines; el shell lo hace antes de pasar la expansión resultante como argumentos aecho.lssabe si está enviando salida a un terminal o no.Ejecutar
lsen un símbolo del sistema escribirá en su pseudo-tty. Redirigir la salida delsgeneralmente no irá a un pseudo-tty, ylsformateará la salida de manera diferente.fuente