The command 'ls -d' is not displaying directories. Is there a way to get 'ls' to only display directories instead of files and directories?

Is there a way to get ls to only display directories instead of files and directories?

From the man page:

 -d, --directory list directory entries instead of contents, and do not derefer‐ ence symbolic links

So if I type it at the / directory I expect to see only directories. Instead it shows "."

$ cd /
$ ls -d
.

I was expecting ls -d to show me this:

$ ls -d
bin data home opt sbin sys var
boot dev lib media proc selinux tmp
cdrom etc lost+found mnt root srv usr

Is there a way to get ls to only display directories instead of files and directories?

6

7 Answers

Your expectations are based upon DOS Think/Windows Think and are wrong. On MS-DOS, Windows, and indeed a few other IBM/Microsoft operating systems, wildcard expansion is done by the command itself, and things like the /a option to the dir command act as attribute filters during wildcard expansion. dir expands wildcards like *, which the command interpreter passes to it as-is, and if /a is specified it applies the appropriate filters to what is returned. (On some operating systems, the attribute filters can be given to the system call for enumerating a directory and the operating system kernel, or its filesystem drivers, applies them itself.)

On Unices and on Linux, wildcard expansion is done by the shell, and is oblivious to permissions. When, in the root directory, you do

ls *

what the ls command itself receives from the shell is (something like)

ls bin home opt var boot dev tmp etc lost+found root usr

What the -d/--directory option does is turn off what normally happens next. What normally happens next is that ls looks at each of its arguments in turn, sees that they are directories, and decides to enumerate their contents. For arguments that name files, it just prints out the information for the file itself. With the -d option, directories are treated just like files. So ls prints out the information for each of the directories that is passed as its arguments, just as it would do if they were files.

So -d is not a "print only directories" option. In fact, not only is there no such option; there cannot be such an option. Wildcard expansion is done by the shell, and (in a POSIX sh at least) there's no way to tell the shell to check permission and file type bits when it expands * into a list of names. To obtain a list of the names of directories alone, it is necessary either to use the find command, as explained by ztank1013, or to use the trick that a pathname ending with a slash implies the directory entry ., as explained by Jin. (Jin's trick ends up with the ls command receiving the arguments

ls bin/ home/ opt/ var/ boot/ dev/ tmp/ etc/ lost+found/ root/ usr/

because the pattern */ is in fact matching pathnames with two components, the second being empty, and so isn't quite doing what was desired. In particular, it will treat symbolic links pointing to directories as if they were directories.)

The behaviour of ls -d without a * is a simple extension of the above. One simply has to know one more thing about ls: When it is given no arguments, it assumes a default argument of .. Now without the -d option, the aforementioned behaviour leads to the contents of the directory named by . being enumerated and the information for its contents displayed. With the -d option, the directory . is treated just as if it were a file, and its own information is displayed, rather than its contents enumerated.

12

You can usels -d */, or ls -d .*/ for hidden directories.

4

Try this

 find . -mindepth 1 -maxdepth 1 -type d

to get just directories under your current location.

0

You might also like

tree -d 

which neatly lists all directories and subdirectories with a graphical depiction of the tree structure.

2

If you want to see directories only with detail like ls -l (ELL) option then you can use below:

find -maxdepth 1 -type d -ls;

Above will only give you the detail like you get with the -l option.

1

If you want to get the job done in another way, try this:

ls -l | grep ^d

Although a single tool is enough in this situation. Pipe line is always there to help you. I like the flexibility in Linux, which I wish you do.

3

I hope this will rectify your need. The below command will list only directories in a given path.

ls -F <path> | grep /

Example:

ls -F ~ | grep /

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like