What is the magic separator between filenames in ls output?
Solution 1
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.
Solution 2
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
Related videos on Youtube
Chris B
Updated on September 18, 2022Comments
-
Chris B almost 2 years
The output of
ls
(with no arguments) appears to separate filenames with linebreaks.Evidence:
ls | grep foo
works as expected, withgrep
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?
-
Blrfl about 12 yearsSpecifically, the function
ls
uses to determine whether or not the output is a terminal isisatty(3)
. -
Daniel Andersson about 12 yearsAlso somewhat related, if one wants to test this in a simple shell script one can run
tty -s
and check its return status.