Listing only directories using ls in Bash?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Listing only directories in Bash looks simple, but the best command depends on whether you want a quick interactive answer or a robust script. ls can do it in some cases, but globbing and find are usually more reliable than parsing formatted ls output.
Core Sections
The simplest ls pattern for visible directories
If you only want non-hidden directories in the current location, this is the usual ls pattern:
The important detail is that the shell expands */ before ls runs. That glob matches names that end with a slash because they are directories, and -d tells ls to print the directory names themselves rather than listing their contents.
This is fine for quick interactive use.
Why ls -l | grep '^d' is weaker
A lot of examples show this pattern:
It works often enough to look correct, but it is less robust because it parses formatted output intended for humans. If names contain strange characters, column spacing changes, or the environment alters the ls format, the pipeline becomes less dependable.
For one-off terminal use it may be acceptable, but for scripting it is usually the wrong tool. In shell work, parsing ls output is a common anti-pattern.
Include hidden directories deliberately
ls -d */ ignores hidden directories because shell globs normally do not match names beginning with a dot. If you want visible and hidden directories together, you need to expand both patterns.
That said, this can also include . and .. depending on shell options and environment. If you are writing a script, be explicit about which names you want rather than assuming the shell behavior will always match your intention.
find is usually better for scripts
For scripting and automation, find is usually more reliable than ls.
This lists directories in the current location, including . itself. If you want only child directories and not the current directory entry, tighten the expression.
find is more explicit and does not depend on shell formatting or terminal-oriented output. It is the better choice when correctness matters more than terseness.
Bash globbing can be enough without ls
If the goal is to loop over directories in a script, you may not need ls at all. Bash globbing is often the cleanest approach.
This avoids spawning ls, keeps the operation in the shell, and works well for many common scripts.
You can then perform actions inside the loop safely:
This is usually better than trying to parse a command’s textual output.
Pick the command based on the job
A good rule of thumb is:
- use
ls -d */for quick interactive inspection - use shell globbing for simple Bash loops
- use
findfor scripts that need predictable behavior, depth control, or hidden-directory handling
The problem is not just "how do I show directories." The real question is "what tool matches the reliability requirements of the task."
Common Pitfalls
- Parsing
ls -loutput withgrepis brittle and is a poor default for scripts. - Forgetting that
*/excludes hidden directories can make the result look incomplete. - Using
find . -maxdepth 1 -type dwithout realizing it includes.can produce one extra line you did not intend. - Reaching for
lsinside Bash loops when a plain glob would be simpler adds unnecessary process overhead and parsing risk. - Assuming shell glob behavior is identical across environments can cause surprises when dotfile settings or shell options differ.
Summary
- '
ls -d */is the quickest interactive way to list visible directories only.' - '
ls -l | grep '^d'works sometimes but is not a robust scripting pattern.' - Use
findwhen you need predictable behavior or more precise control. - In Bash scripts, direct globbing is often better than invoking
lsat all. - Choose the approach based on whether you are exploring interactively or writing something that must be reliable.

