When you pipe the output, ls acts differently.
This fact is hidden away in the info documentation:
If standard output is a terminal, the output is in columns (sorted vertically) and control characters are output as question marks; otherwise, the output is listed one per line and control characters are output as-is.
To prove it, try running
ls
and then
ls | less
Working on a little script the other day I had the need to determine if the input to the script was coming from a pipe or from the terminal. Seems like a simple enough thing to determine but nothing jumped immediately to mind and a quick internet search didn't help much either. After a bit of pondering I came up with two solutions: the stat command and using information from the proc file system.
R. Sałustowicz, M. Wiering, and J. Schmidhuber. Progress in Connectionist-based Information Systems:
Proceedings of the Fourth International Conference on
Neural Information Processing ICONIP'97, 1, page 502--505. Springer-Verlag, (1997)
R. Sałustowicz, M. Wiering, and J. Schmidhuber. Proceedings of the Seventh International Conference on
Artificial Neural Networks (ICANN'97), volume 1327 of Lecture Notes in Computer Science, page 769--774. Springer-Verlag, (1997)
R. Franke, F. Casella, M. Sielemann, K. Prölß, M. Otter, and M. Wetter. Proceedings of the 7th International Modelica Conference, volume 43 of Linköping Electronic Conference Proceedings, page 122--131. Linköping, Linköping University Electronic Press, Linköpings universitet, (2009)