ls is a very useful command for getting listings, but it is often misused by being parsed in scripts to get filenames or file data from the output. The problem with this is that ls is designed for human users to read, not other programs.
You may have seen bad code like this on the web:
# Bad code
$ grep pattern `ls` $ for file in `ls` ; do grep pattern $file ; done
This fails as soon as there is a filename with any special characters in it, such as a space, an asterisk, or a semicolon:
$ ls -1 programming recipes file with spaces file* # Bad code
$ grep pattern $(ls) grep: file: No such file or directory grep: with: No such file or directory grep: spaces: No such file or directory
It is always better to use globs or find in this situation. If you only have to deal with one directory, use globs, as the commands tend to be simpler:
$ grep pattern -- *
$ find . -type f -exec grep pattern -- {} \;
You can loop over globs the same way with for:
$ for file in * ; do grep -F pattern -- "$file" ; done
We'll learn more about globs in Chapter 5, Variables and Patterns, and build on that for loops in Chapter 6, Loops and Conditionals.
To summarize: never use ls in scripts unless it's only for a human running your script to read. Resist the temptation to parse the output yourself, and look for a safer way to do it instead.