Why does “ls | wc -l” show the correct number of files in current
directory?
Well, that's a false premise right there. It does not! Try this:
mkdir testdir
cd testdir
# below two lines are one command, the newline is quoted so will be part of argument
echo text | tee "file
name"
ls -l
ls | wc -l
Output of that last line is 2.
Note how, when printing to the console in ls -l
command, ls will not print the newline as is, but will instead print ?
. But this is a specifically implemented feature of ls, it does this when it detects the output is going to an actual terminal, to avoid funny file names from messing the terminal up. This same detection determines if file names are printed one-per line (in pipe) or according to terminal width (which obviously only makes sense if there is a terminal with width). You can fool ls with command like ls | cat
if you want the raw file names printed, separated with newlines.
wc -l
just counts number of lines, and if a file name happens to contain a newline, well then wc will count it as two lines.
ls also has switches to force hiding control chars, -q
/--hide-control-chars
, so ls -q | wc -l
should actually give accurate number of files listed by ls
(which usually is not same as actual number of files in the directory, without -a
switch), because then only newlines in ls output should be those separating file names.
ls
before you read this explanation. Be aware of the pitfalls. – ignis Sep 25 '14 at 15:27