Why does “ls | wc -l” show the correct number of files in current
Well, that's a false premise right there. It does not! Try this:
# below two lines are one command, the newline is quoted so will be part of argument
echo text | tee "file
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,
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.