Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

The output of ls (with no arguments) appears to separate filenames with linebreaks.

Evidence:

  • ls | grep foo works as expected, with grep treating each filename as a separate line of input.

  • ls > files.txt; vim files.txt --> in Vim, each file is on a separate line

And yet in the terminal the output of ls puts multiple files on one line, separating the filenames with spaces to make nicely aligned columns:

$ ls
a.txt  b.txt  c.txt

So my question is, how does ls do this?

Is it using some special control char to 'fake' a newline? Or does it know when its output is being piped to another command, and format its output differently in this case?

share|improve this question
add comment

2 Answers

up vote 20 down vote accepted

Or does it know when its output is being piped to another command, and format its output differently in this case?

Yes. From the full manual (available through info ls if the documentation is installed):

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.

If you like the one column output, you can run

ls -1

to get it in the terminal as well.

share|improve this answer
4  
Thanks. As usual, I should have RTFM! –  Chris B May 14 '12 at 11:10
7  
Specifically, the function ls uses to determine whether or not the output is a terminal is isatty(3). –  Blrfl May 14 '12 at 14:37
    
Also somewhat related, if one wants to test this in a simple shell script one can run tty -s and check its return status. –  Daniel Andersson May 14 '12 at 16:39
add comment

ls detects it when you pipe its output. You can see it in the 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.

If you want each file in the output to be placed on a separate line regardless of the pipe redirection, you can use

ls -1
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.