About the rmdir Command
The rmdir (remove directory) command is used to delete empty directories in Linux and Unix systems. Unlike rm -r which can recursively delete directories with all their contents, rmdir only removes empty directories, making it a safer choice when you want to ensure you're not accidentally deleting files. If a directory contains any files or subdirectories, rmdir will refuse to delete it and display an error message.
Key safety feature: The rmdir command's refusal to delete non-empty directories is a protective measure that prevents accidental data loss. This makes it the preferred command for cleaning up empty directory structures, especially in scripts where you want to remove only truly empty directories without risking file deletion.
Common use cases: Cleaning up empty build directories, removing old empty cache folders, tidying up directory structures after moving files, and safely removing temporary directory hierarchies that should be empty.
Detailed Examples
1Basic Directory Removal
Remove a single empty directory.
rmdir empty_folder command successfully removes the empty directory. Notice that the directory must be completely empty - no files, no hidden files, no subdirectories. The command completes silently with no output when successful (typical Unix behavior). After removal, the directory no longer appears in the listing. Important behavior: If the directory contains any files (including hidden files like .gitignore), rmdir will fail with an error message "rmdir: failed to remove 'directory': Directory not empty". This safety feature prevents accidental deletion of files.
ls -la directory before rmdir to verify the directory is truly empty. The -a flag shows hidden files that might prevent removal.2Attempting to Remove Non-Empty Directory
Understanding what happens when you try to remove a directory that contains files.
file.txt, so rmdir fails. The command returns exit status 1 (failure) which can be checked with $?. This protective behavior is rmdir's main feature - it will never delete files. If you see this error: You have three options: (1) Manually delete or move the files first, then use rmdir. (2) Use rm -r directory to recursively delete everything (dangerous!). (3) Use rmdir --ignore-fail-on-non-empty directory to suppress the error but leave the directory intact. Option 1 is safest when you want to ensure no important files are accidentally deleted.
if rmdir directory; then ... else ... fi for conditional execution.3Remove Multiple Empty Directories
Delete several empty directories in a single command.
logs contains files, rmdir would remove cache, temp, and old_backups successfully but fail on logs with an error message. This partial success is useful - you don't need all directories to be empty for the command to be worthwhile. The command processes each directory independently.
rmdir */ attempts to remove all subdirectories in the current directory. Only empty ones will be removed, but verify what you're targeting before running it.4Verbose Mode
Using -v flag to see confirmation of what's being removed.
-v (verbose) flag makes rmdir report each directory as it's removed. This provides confirmation that operations are happening as expected, which is particularly useful in scripts or when removing many directories. The verbose output goes to standard output, so it can be captured in logs. Why use verbose: (1) Confirmation - you see exactly what was removed. (2) Debugging - if a script fails, you can see how far it got. (3) Logging - capture what was cleaned up for audit trails. (4) Learning - understanding the command's behavior by seeing its actions. In production scripts, verbose output is valuable for troubleshooting and maintaining audit logs of filesystem changes.
rmdir -v old_dirs/* 2>&1 | tee cleanup.log captures both successful removals and error messages to a log file.5Remove Parent Directories (-p flag)
Recursively remove a directory and its empty parent directories.
-p (parents) flag removes not only the specified directory but also its parent directories if they become empty after the removal. In this example, empty is removed first, which leaves archived empty, so it's removed. Then old becomes empty and is removed, then 2023, and finally projects. The entire directory hierarchy is cleaned up in one command. Important condition: The -p flag only removes parent directories that become empty as a result of the removal. If any parent directory contains other files or directories, rmdir stops at that level. For example, if 2023 contained another directory called current, rmdir would remove empty, archived, and old, but stop at 2023 because it's not empty. This is the inverse of mkdir -p which creates parent directories.
rmdir -p /home/user/projects/test could theoretically remove /home/user/projects, /home/user, and even /home if they all became empty (which is unlikely but possible in edge cases). Always use relative paths or verify the hierarchy.6Ignore Failures on Non-Empty Directories
Suppress errors when encountering non-empty directories.
--ignore-fail-on-non-empty flag tells rmdir to silently skip directories that contain files rather than reporting an error. In this example, empty1 and empty2 are successfully removed, while has_files is left intact because it contains data.txt. No error message is displayed for has_files. Use case: This is valuable in cleanup scripts where you want to remove all empty directories but don't care about (or want to preserve) non-empty ones. For example, cleaning up a build directory structure where some output directories are empty (can be removed) and others contain build artifacts (should be kept). The command succeeds (exit status 0) even if some directories couldn't be removed. This is different from standard behavior where encountering a non-empty directory causes rmdir to return exit status 1.
7Using rmdir in Scripts for Safe Cleanup
Practical script example for cleaning up empty directories.
find command locates all empty directories (-type d -empty), then the while loop processes each one. Using -print0 and read -r -d '' handles directory names with spaces or special characters safely. Each removal is logged with a timestamp. The script captures both successful removals and failures. Key safety features: (1) Only targets empty directories (find's -empty flag). (2) Uses rmdir which won't delete files. (3) Logs all actions for audit trail. (4) Handles edge cases like spaces in directory names. (5) Doesn't fail completely if one removal fails. This pattern is production-ready and demonstrates best practices for automated filesystem maintenance.
8Combining with find for Bulk Operations
Advanced usage: finding and removing all empty directories in a tree.
find command with -type d -empty locates all empty directories recursively. Two approaches are shown: (1) -delete flag removes them directly (fast but no feedback). (2) -exec rmdir -v {} \; uses rmdir on each one (verbose output for confirmation). The second approach is safer because rmdir will refuse if the directory somehow became non-empty between find identifying it and rmdir attempting removal. Important note: The find command processes directories depth-first when using -delete, which matters because removing a subdirectory might make its parent directory empty. The -exec approach with rmdir handles this naturally. Parent directories like build, docs, and tests remain because they still contain something (in this case, subdirectories or files).
9Checking Before Removal
Defensive programming: verify directory is empty before removal.
ls -A to check for contents (including hidden files - the -A flag shows all except . and ..). (4) Only attempts removal if truly empty. (5) Reports success or failure clearly. The ls -A trick: ls -A directory returns empty output if the directory is empty, non-empty output if it contains anything. The test [ -z "$(ls -A "$dir")" ] checks if the output is empty (zero-length string). This catches hidden files that a simple ls would miss. This pattern is excellent for interactive scripts where you want to be absolutely certain before removing directories, or when you want to provide detailed feedback about why removal failed.
10Cleaning Up Directory Trees Bottom-Up
Advanced technique: removing nested empty directories from deepest to shallowest.
find -depth processes directories depth-first, meaning deepest directories are encountered first. This ensures child directories are removed before their parents, allowing the parents to become empty and be removed in turn. The -depth flag is crucial - without it, find might try to remove a parent before its children, causing failures. Approach 2: rmdir -p does this automatically, climbing up the directory tree and removing empty ancestors. Both achieve the same result but -p is simpler when you know the full path. The find approach is more flexible for finding and removing all empty directory chains in a tree structure. Real-world use: This is perfect for cleaning up directory structures created by build systems, temporary file hierarchies, or scaffolding that's no longer needed.
Command Options Reference
| Option | Long Form | Description |
|---|---|---|
-p |
--parents |
Remove directory and its ancestors (empty parent directories) |
-v |
--verbose |
Output a diagnostic message for every directory processed |
--ignore-fail-on-non-empty |
Ignore failures that are due to directories not being empty | |
--help |
Display help message and exit | |
--version |
Output version information and exit |
rmdir vs. rm -r: Critical Differences
Understanding the Key Differences
| Feature | rmdir | rm -r |
|---|---|---|
| Can delete files | ❌ No - only empty directories | ✅ Yes - deletes everything |
| Removes non-empty dirs | ❌ No - refuses with error | ✅ Yes - recursive deletion |
| Safety level | 🟢 Very safe - won't delete files | 🔴 Dangerous - can delete everything |
| Requires confirmation | No - safe by design | No (unless using -i flag) |
| Use when | You want to remove ONLY empty directories | You need to remove directory with contents |
| Error on non-empty | Yes - this is a feature | No - deletes everything silently |
| Hidden files matter | Yes - .hidden files prevent removal | No - deletes hidden files too |
rm -rf is one of the most dangerous commands in Linux. It recursively deletes everything without confirmation. NEVER run rm -rf without being absolutely certain of the path. A typo can destroy your entire system. Always use rmdir when you only want to remove empty directories.
When to Use Which Command
- Use rmdir when:
- You want to remove only empty directories
- You want to be safe and avoid accidental file deletion
- You're cleaning up directory structures that should be empty
- You want an error if the directory isn't empty (indicating something unexpected)
- Writing scripts where safety is paramount
- Use rm -r when:
- You explicitly want to delete a directory and all its contents
- You've verified what you're deleting (use ls -R first)
- You're removing temporary or build directories that should go away
- Consider using rm -ri for interactive confirmation on each file
Best Practices and Safety
Safe Directory Removal Guidelines
- Always verify before removing: Use
ls -la directoryto check contents before rmdir - Check for hidden files: Hidden files (starting with .) prevent removal - use
ls -Ato see them - Use absolute paths in scripts: Avoid confusion about which directory you're removing
- Test with echo first: In scripts, test with
echo rmdir $dirbefore actually running rmdir - Log removals: Keep audit trails of what was removed and when, especially in production
- Use -v in scripts: Verbose output helps with debugging and logging
- Prefer rmdir over rm -r: When possible, use rmdir's safety features
- Handle failures gracefully: Check exit status and don't assume rmdir succeeded
- Be careful with wildcards:
rmdir *tries to remove all subdirectories - verify first - Document expectations: If a directory should be empty, document why in your scripts
Common Patterns and Idioms
- Safe removal with verification:
[ -z "$(ls -A dir)" ] && rmdir dir || echo "Directory not empty" - Remove if empty, create if missing:
rmdir dir 2>/dev/null; mkdir -p dir - Remove all empty subdirectories:
find . -type d -empty -delete - Conditional removal in scripts:
if rmdir "$dir" 2>/dev/null; then echo "Removed"; fi - Remove with logging:
rmdir -v dir 2>&1 | tee -a removal.log
Common Use Cases
Cleanup After File Migration
Build System Cleanup
Temporary Directory Cleanup
Project Structure Cleanup
Troubleshooting Common Issues
Cause: Hidden files exist. Solution: Use
ls -a directory to see all files including those starting with dot (.). Hidden files like .gitkeep, .DS_Store, or .hidden prevent removal.
Cause: Relative path confusion or wrong current directory. Solution: Always use absolute paths in scripts, or verify pwd before running rmdir. Test with echo first.
Cause: Don't have write permission on parent directory. Solution: Check permissions with
ls -ld parent_directory. Need write permission on the parent directory (not the directory being removed) to remove directories.
Cause: Directory is mounted, or you're in the directory. Solution: (1) Check
mount output for mounted filesystems. (2) Don't be inside the directory you're removing - cd out first. (3) Check if another process has the directory open with lsof | grep dirname.
Cause: Parent directories were unexpectedly empty. Solution: This is actually working as designed, but be careful with paths. Verify the full path before using -p, especially with paths starting at root.
Related Commands
- rm: Remove files or directories (use -r for directories, -rf for recursive force deletion)
- mkdir: Create directories (opposite of rmdir)
- find: Find files and directories (often used with -empty and -delete)
- ls: List directory contents (use -A to check if directory is empty)
- mv: Move directories (alternative to deleting)
- tree: Display directory tree structure
- du: Disk usage (du -sh directory checks size before removal)
Exit Status Codes
- 0: Success - all directories were successfully removed
- 1: Failure - one or more directories could not be removed (non-empty, doesn't exist, permission denied, etc.)
Check the exit status in scripts with $? or by using rmdir in conditional statements: if rmdir dir; then ...; fi