3

I wish to list all directories only (not files) in my current dir. I expected ls -ld ./* to return only directories as man page states

list directories and not contents

Currently the command returns all files and directories under current directory.

Alternatively I have the below command which can achieve my requirement but i was thinking if there was an inbuilt option to achieve the same

ls -lF ./ | grep ".*/$"
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • 3
    -d will prevent ls from descending into directories - it won't prevented from listing files that are part of the shell's expansion of the ./* glob – steeldriver Jun 04 '18 at 18:18
  • So is there an inbuilt argument to achieve the same instead of adding grep alternative given above ? – LoveWithMaths Jun 04 '18 at 18:19
  • the -d flag does instruct ls to return any directory as the entry itself instead of listing the contents of the directory. If you are listing a set of entries however, -d does not examine each argument and return only those that are directories - it will list every argument that you indicated. – doneal24 Jun 04 '18 at 18:19
  • @linuxuser No. If you give the command ls filename, then ls will return the information about filename. You might try find . -maxdepth 1 -type d -ls – doneal24 Jun 04 '18 at 18:21
  • @muru: this really seems to be a duplicate question. – schily Jun 04 '18 at 18:30

3 Answers3

3

While the -d flag does prevent ls from descending into directories, that is literally exactly what it does. It does not mean list only directories. There is a subtle difference between these two statements in that if you run ls -d some_file, then ls is going to show you some_file. Since you are using shell globbing (./*), this glob is expanding to include the files in the current directory, as well as the directories in the current directory. Since the shell is what performs globbing and expansion, and not ls, the ls is receiving a list of files.

To work around this, you need to ensure the shell glob does not include regular files. You can do this by using a trailing / on the glob. Since / is a special character forbidden in file names, but which denotes the separation between directories, you can use it to match only directories.

So for example:

ls -d */
phemmer
  • 71,831
  • Yeah! i did get it after doing trying some commands on shell. Infact i answered my own question once i understood. – LoveWithMaths Jun 04 '18 at 18:41
  • Whether cat /etc/passwd/ prints the content of the file depends on the OS. In 1992, it was required to print the file. On such a system, the results depend on the shell's glob implementation. IIRC, around 2004, file/ was required to only open directories. On such a system, the behavior is independent from the shell. – schily Jun 04 '18 at 18:42
2

This may depend on your shell.

most modern POSIX compliant shells list only directories if you append a slash to the star:

echo */

So if you call:

ls -l */

you get the kind of listing you expect.

If you don't like to see the content of the directories, call:

ls -ld */
schily
  • 19,173
0

Basically my confusion was why ls -ld ./* dint returned dirs only. ls argument expects a dir for which you wish to list. And since the argument */ got evaluated by shell to all files and directories (because of wildcard); everything got listed including the files under the sub-directory. Solution as suggested by many of you was ls -ld */; the wildcard here got expanded to directories only and excluded the files.