How to remove a directory in Linux?

How to remove a directory in Linux?

You run rmdir on a folder you just created and it works, then you run the same command on a folder with a single file inside and get Directory not empty. That split is the whole design of directory removal in Linux, and once you see which tool guards against data loss and which one deletes recursively, the right command becomes obvious.

Which command to use and when

If you want a quick decision before you read the examples, use this map. rmdir is the safe empty-only remover and rm with -r is the recursive remover for anything with contents.

Adding -f suppresses prompts. Use -i or -I when you want the command to ask before it deletes.

GoalCommandWhat it does
Remove an empty directoryrmdirFails if anything is inside, so you cannot delete by accident
Remove nested empty directories at oncermdir -pWalks up and removes each empty parent
Remove an empty directory with rmrm -dSame guard as rmdir but via rm
Remove a directory with filesrm -rRecurses into every child and deletes
Force recursive delete without promptsrm -rfIgnores write-protected prompts and missing files
Confirm before each deletionrm -ri / rm -rIAsks for each item or once for large trees

Every rm and rmdir deletion is permanent. Files do not go to Trash, and the tools do not keep a recycle log. I verified each command below on Ubuntu 22.04 with GNU coreutils 8.32 before updating this guide, so the outputs match what you will see on a current distribution.

Remove an empty directory with rmdir

Use rmdir when you know the directory is empty and you want the command to stop you if you are wrong. The guard is the feature.

mkdir demo_empty
ls -ld demo_empty
rmdir demo_empty
echo "removed"
ls

When the directory is not empty, rmdir prints a clear error and leaves everything in place.

mkdir -p demo_nonempty
touch demo_nonempty/file.txt
rmdir demo_nonempty
# rmdir: failed to remove 'demo_nonempty': Directory not empty
rmdir empty vs non-empty error in Linux terminal
rmdir removes an empty directory and fails when the directory contains files

Add -v when you want to see each directory as it goes, and –ignore-fail-on-non-empty when you are cleaning a list and want the command to skip non-empty entries without exiting on error. Use an absolute or relative path if you are not inside the parent directory.

Remove nested empty directories with rmdir -p

The -p flag removes a chain of empty parents in one step. It deletes the innermost directory first and then tries each parent. It stops at the first parent that is not empty, which means you do not need a loop of rmdir calls.

mkdir -p a/b/c
find a -type d | sort
rmdir -p a/b/c
echo "removed chain a/b/c"
ls

This only works when every directory in the chain is empty. If a file exists anywhere inside, rmdir -p removes the empty tail and then reports Directory not empty for the first non-empty ancestor.

Remove directories with rm: -d, -r, and -rf

rm is the general remover. Without flags it refuses directories. With flags it covers the same cases as rmdir and the recursive cases that rmdir cannot touch.

rm -d for an empty directory

mkdir demo_rm_d
rm -d demo_rm_d
echo "removed with rm -d"

rm -r for a directory with contents

The -r flag means recursive. rm walks every file and subdirectory inside the target and removes them before removing the target itself. This is how you delete a project folder with source files and nested directories in one command.

mkdir -p myproject/src
touch myproject/file.txt myproject/src/app.js
ls -R myproject
rm -r myproject
echo "myproject removed"
ls
rm -r removing non-empty directory recursively in Linux
rm -r deletes a directory and all of its contents recursively

rm -rf to force removal without prompts

When a file is write-protected, plain rm -r prompts for confirmation. Adding -f tells rm to ignore nonexistent files and to suppress that prompt.

Combine them as -rf for a forced recursive delete. I tested this with a 444 file to confirm the prompt suppression.

mkdir -p demo_rf
touch demo_rf/file.txt
chmod 444 demo_rf/file.txt
ls -l demo_rf/
rm -r demo_rf
# rm: remove write-protected regular empty file 'demo_rf/file.txt'?
rm -rf demo_rf
echo "forced removal done"

Never run rm -rf with a variable that might be empty. The classic failure is rm -rf “$DIR”/* when DIR is unset and the shell expands it to rm -rf /*. Guard with : “${DIR:?not set}” or test that the directory exists before you delete.

Confirm before you delete: -i and -I

When you are unsure what is inside, ask rm to confirm. The -i flag prompts for every file and directory. The -I flag prompts once when you are about to delete a handful of files (GNU rm prompts once before removing recursively when the count is large) or recurse, which is quieter for large trees.

mkdir -p demo_i
touch demo_i/a.txt demo_i/b.txt demo_i/c.txt
rm -ri demo_i
# rm: descend into directory 'demo_i'?
# rm: remove regular empty file 'demo_i/a.txt'?

mkdir -p demo_i2
touch demo_i2/{1..5}.txt
rm -rI demo_i2
# rm: remove 1 argument recursively?

Answer y to confirm and n to skip. Use -I as a everyday safety net and reserve -i for cases where you want to approve each file.

Wildcards, find, and safer approaches

rm understands shell globs, so you can match multiple directories by name without listing each one.

mkdir -p wd/folder1 wd/folder2 wd/folder3 wd/other
ls wd/
rm -r wd/folder*
ls wd/

The * matches any number of characters and ? matches exactly one. Quote the expression when you want find to do the matching instead of the shell, and add safeguards for names with spaces or leading dashes.

# Safer: use -- to stop option parsing and quote the path
rm -r -- "./-oddly-named"

# Use find for selective deletes
find ./projects -maxdepth 1 -type d -name "build-*" -exec rm -r -- {} +

# Preview before you delete
find . -type d -name "__pycache__" -print
find . -type d -name "__pycache__" -exec rm -r -- {} +

# Verbose so you see what happened
rm -rv old_cache/
rmdir -p and wildcard removal in Linux terminal
rmdir -p removes nested empty directories and rm -r with a wildcard removes matching directories

Two flags deserve a permanent place in your muscle memory. –preserve-root is the default in GNU rm and blocks rm -rf / from destroying the system.

Do not pass –no-preserve-root unless you have a specific reason. –one-file-system keeps a recursive rm from crossing mount points.

Recovery and safer alternatives

Neither rm nor rmdir moves files to Trash. Once they return, the data is gone unless you have a backup or filesystem snapshot. For day-to-day safety, install a Trash-aware remover or alias the risky form.

# Trash-based alternative (install once)
sudo apt install trash-cli
trash-put myproject/
trash-list
trash-restore
trash-empty

# Quick safety alias
alias rm='rm -I --preserve-root'
# For scripts, use full rm and explicit flags

Treat trash-cli or gio trash as a separate workflow from rm. It is useful on a desktop but you should still know the underlying rm behavior for servers where Trash is not available.

Common errors and fixes

rm and rmdir report the same handful of errors on every distribution, so matching the message to the fix saves time.

ErrorCauseFix
rmdir: Directory not emptyFiles remain insideUse rm -r if you intend to delete contents, or empty the directory first
rm: cannot remove ‘dir’: No such file or directoryTypo or wrong pathCheck pwd and ls, use tab completion
rm: cannot remove ‘dir’: Permission deniedMissing write or execute on parentCheck ls -ld and sudo only when you own the workflow
rm: remove write-protected file?444 or read-only fileUse rm -rf to suppress, or chmod +w first
rm: refusing to remove ‘.’ or ‘..’Dot entry protectionUse an explicit name, not * with a leading dot

Conclusion

Start with rmdir when you expect an empty directory and want a built-in stop on anything unexpected. Reach for rm -r when the directory has contents, add -f only when you mean to skip prompts, and keep -I as your everyday confirmation. Check the path with ls or find -print first, keep the — separator in mind for odd names, and remember that deletion is permanent.

What is the difference between rmdir and rm -r?

rmdir removes only empty directories and fails with Directory not empty if any file remains, which makes it the safer default. rm -r removes a directory and everything inside it recursively. Use rmdir when you expect emptiness and rm -r when you intend to delete contents.

How do I force remove a directory with contents?

Use rm -rf directory_name. The -r flag recurses into contents and -f suppresses confirmation for write-protected files. Verify the path with ls or pwd first because rm -rf is permanent and does not use Trash.

Can I restore a directory deleted with rm?

No. Both rm and rmdir delete permanently. Restore from a backup or filesystem snapshot. On desktops you can use trash-cli or gio trash instead of rm when you want Trash behavior.