La salida de ls(sin argumentos) parece separar los nombres de archivo con saltos de línea.
Evidencia:
ls | grep foofunciona como se espera, con elgreptratamiento de cada nombre de archivo como una línea de entrada separada.ls > files.txt; vim files.txt-> en Vim, cada archivo está en una línea separada
Y, sin embargo, en la terminal, la salida de lspone múltiples archivos en una línea, separando los nombres de los archivos con espacios para formar columnas bien alineadas:
$ ls
a.txt b.txt c.txt
Entonces mi pregunta es, ¿cómo hace esto?
¿Está usando algún carácter de control especial para 'falsificar' una nueva línea? ¿O sabe cuándo su salida se canaliza a otro comando y formatea su salida de manera diferente en este caso?

lsutiliza para determinar si la salida es o no un terminalisatty(3).tty -sy verificar su estado de retorno.lslo detecta cuando canaliza su salida. Puedes verlo en la documentación:Si desea que cada archivo en la salida se coloque en una línea separada independientemente de la redirección de la tubería, puede usar
fuente