0

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.

  • 4
    type echo .* and think. – Ipor Sircer Jan 2 '17 at 18:48
4

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).

  • -1 That's not an accurate description of what -d does in general. – DepressedDaniel Jan 2 '17 at 19:04
  • Answer updated to correct the -d deficiency. – John Jan 2 '17 at 19:26
3

Why does ls .* print out the contents of the hidden directories?

When ls is given a directory, it prints the contents of that directory (by default, excluding hidden files in that directory). With ls .*, the shell has given ls a list of files and directories beginning with .

You can use set -x to see the command being invoked by the shell (i.e., after expanding shell globs).

2

When you do

$ ls directory

you will get the listing of directory. If directory is a directory, the contents of it will be listed, otherwise it will be listed as any other file.

When you do

$ ls dir*

you will get a listing of all things that matches dir*. If any of those things are directories, you will see the contents of those directories.

When you do

$ ls .*

you will get the same effect as in the previous example, only the pattern is different, and since you explicitly match hidden file and folders, these (the matching ones) will be considered by ls.

Use ls with its -d flag if you're not interested in seeing the contents of a folder (hidden or not). It stops ls from recursing into any found folder that matches the pattern you give it.

1

Because you tell it to, specifically. In case the shell glob expansion part was obvious to you, I guess the answer you really needed regarded the confusion behind your question.

You're confusing what you give ls with what ls gives you. While ls won't give you hidden directories/files, you can give it hidden directories/files to list. Which you did by using .* specifically (the emphasis is on . not on *).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.