ls Wildcards – Why Does ‘ls .*’ Show Contents of Hidden Directories?

lswildcards

Why does ls .* print out the contents of the hidden directories? I want to print just the hidden files, and now see that Show only Hidden Files is a solution to this, yet I sill want to understand why the contents of the directories are shown. The contents of further nested directories are not shown.

Below is a partial output of ls .* in my home directory.

.bash_history
.bash_profile
.bashrc
.coin_history
.emacs
.gitconfig
.gitignore_global
.grasp_jss

.ssh:
config          github_rsa.pub  id_rsa.pub      known_hosts.old
github_rsa      id_rsa          known_hosts     lambda.pem

.vim:
colors   ftdetect syntax

This machine is running RHEL. Similar behavior observed on Mac OSX.

Best Answer

Short answer: shell glob expansion.

The shell takes your input and expands the .* part before passing it to ls, so effectively you're doing:

$ ls .bash_history .bash_profile .bashrc .coin_history .emacs ...

So it lists each entry. When it sees a directory entry, it lists the contents of that directory, just as you would expect ls to do. To see only the files/directories in your working directory, use the -d option to ls:

$ ls -d .*

The -d option tells ls to "list directories themselves, not their contents" (taken from the lsman page).