Skip to content
Go back

Recursively delete all empty subdirectories

Updated:
By SumGuy 5 min read
Recursively delete all empty subdirectories

Why your filesystem collects empty directories like lint traps

You move a bunch of files out of a deeply nested folder structure. Copy data to a new server. Reorganize a project. And suddenly you’ve got ghost directories — empty folders scattered throughout the tree like breadcrumbs nobody swept up.

They’re not hurting anything, but they clutter your backups, make navigating harder, and they’re the kind of tech debt that eventually someone (future you at 2 AM) will fix by hand. Recursively. Across 50 subdirectories. Fun times.

The good news: Unix gives you surgical tools to clean this up. The bad news: the tools are aggressive, so you need to understand what you’re doing first.

The classic one-liner: find + rmdir

Here’s the approach most people reach for:

Recursive directory deletion with find
find /home/user/somedir -depth -type d -empty -exec rmdir {} \;

Let me break this down:

The -depth flag is crucial. If you delete parent folders before children, the parent might not be empty anymore, and you’ll leave orphans behind. By processing depth-first, you clean bottom-up.

But first: the dry run

Listen. I’m gonna be direct: do a dry run first. Every time. No exceptions.

Preview what will be deleted
find /home/user/somedir -depth -type d -empty

Run that command first. Look at the output. Make sure those are actually the directories you want gone. This takes 30 seconds and saves your bacon.

If the output looks reasonable, then run the deletion command.

Using find’s built-in -delete flag

Modern versions of find have a -delete action that’s faster and safer than -exec rmdir:

Using find's native delete action
find /home/user/somedir -depth -type d -empty -delete

No rmdir needed. Same effect, one fewer process spawned. If your find supports it (it probably does), prefer this.

Still do the dry run first — just swap -delete for nothing.

What about hidden directories?

Hidden directories (ones starting with .) are included by default in find. If you want to exclude them:

Skip hidden directories
find /home/user/somedir -depth -type d -empty ! -name '.*' -delete

The ! -name '.*' means “don’t match anything that starts with a dot.” This is useful if you’re cleaning out a project directory but want to preserve .git subdirectories (even if they’re empty, which they shouldn’t be).

Alternative: rmdir with —ignore-fail-on-non-empty

If you want less automation and more control, you can feed directories to rmdir directly:

Using rmdir with safety flag
find /home/user/somedir -depth -type d -empty -print0 | xargs -0 rmdir --ignore-fail-on-non-empty -v

Breaking it down:

This is slower than find -delete but gives you more control and better error handling if something goes sideways during deletion.

A preview script before committing

If you’re nervous (and you should be, at first), here’s a shell script that shows you exactly what will be deleted before asking for confirmation:

safe-rm-empty-dirs.sh
#!/bin/bash
DIRPATH="${1:-.}"
echo "=== Preview: empty directories to be deleted ==="
find "$DIRPATH" -depth -type d -empty | sort
echo ""
read -p "Delete these? (yes/no): " confirm
if [[ "$confirm" == "yes" ]]; then
find "$DIRPATH" -depth -type d -empty -delete
echo "Done!"
else
echo "Aborted."
fi

Run it: ./safe-rm-empty-dirs.sh /path/to/clean

It’s not fancy, but it forces you to look at what’s happening and explicitly confirm. That’s the entire point.

Edge cases and gotchas

Symlinks: find -type d will follow symlinks and delete the actual directory they point to, not the link itself. If that’s not what you want, add -not -L before -type d:

Avoid following symlinks
find /home/user/somedir -depth -not -L -type d -empty -delete

Permission errors: If find encounters a directory you don’t have permission to read, it’ll skip it. The output might say “Permission denied” for some branches. That’s expected. You can silence those with 2>/dev/null if they’re noise:

Suppress permission errors
find /home/user/somedir -depth -type d -empty -delete 2>/dev/null

Race conditions: If another process is creating files in these directories while find runs, you might leave some behind. This is rare, but if you’re cleaning a live directory, that’s a risk.

The real lesson

Empty directories themselves aren’t evil. But they’re organizational debt. Clean them up once in a while, but do it carefully — think about what you’re deleting, preview first, and you’ll be fine.

Your future self will appreciate the tidy filesystem.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Three ways to upload ISOs to Proxmox
Next Post
Remove all old installed but unused kernels

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts