I can find the subdirectories of a directory by

ls -d -- */


ls -l | grep "^d"

but both of these seem indirect, and I would imagine that there would be a standard way to find just the directories. Is there a right way to do this? And if not, will either of these lead to undesirable behavior on edge cases? (Symbolic links, hidden directories, etc.)


The answer will depend more on what you intend to do with the output than on what you are looking for. If you just want to see a list for visual reference at the terminal, your first solution is actually pretty nice. If you want to process the output you should consider using another method.

One of the most robust ways to get a list to feed into another program is to use find.

find -maxdepth 1 -type d

The reason this is good for feeds is that find can output the data separated by nulls using -print0 or properly escape strings as arguments to another programs using -exec. For reference on why this is better than parsing the output of ls, see ParsingLS on Greg's Wiki.

  • 4
    I had to type find . -maxdepth 1 -type d to get this to work on OS X Yosemite.
    – Sean Levin
    Feb 22 '15 at 12:18
  • 4
    to list the sub-directories, one has to also specify -mindepth as in find . -maxdepth 1 -mindepth 1 -type d. Otherwise, the current directory . will be included.
    – tinlyx
    Dec 25 '19 at 23:02

FYI - In ZSH (but not BASH), you can also do this: ls -d -- *(/); the (/) modifier tells ZSH only to glob directories.

That said, it isn't very different from your own proposed solution (ls -d -- */), and it's far from standard.

As far as the output of ls (which probably differs based on other flags):

% ls
dir0 dir1 dir2 file0 file1 file2
% ls -d -- */
dir0/ dir1/ dir2/
% ls -d -- *(/)
dir0 dir1 dir2
  • zsh expands the asterisk to all files and directories, the (/) flag selects parts of that expansion so ls *(/) would also work, as well as echo *(/), or a more zshly way print -l *(/). The two first versions also work in bash.
    – Thor
    Apr 13 '12 at 9:17
  • 1
    Note that *(/) expands to the non-hidden directories while */ expands to non-hidden directories or symlinks to directories (or at least symlinks to paths for which we can tell that they are directories). Feb 23 '13 at 22:02

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.