Linux下如何用pathlib重命名目录并覆盖已存在目标目录?
Great question! Let's break down why you're hitting that Directory not empty error, then go through the best solutions for your Linux environment—including both pure Python approaches and a more efficient system-level trick.
Why pathlib.replace() Fails
On Linux, pathlib.Path.replace() relies on the POSIX rename() system call under the hood. The catch? This system call won't let you replace a non-empty directory directly—it only works unconditionally if the target is an empty directory or a regular file. The cross-platform documentation simplifies this detail, but Linux enforces this restriction, which is exactly what's causing your error.
Method 1: Delete Target First, Then Rename (Pure Python)
This is the most straightforward approach using Python's built-in libraries. We first recursively delete the existing Previous directory, then rename Current to take its place. While this has a small risk of data loss if the process is interrupted mid-delete, it aligns perfectly with your "full overwrite" requirement:
from pathlib import Path import shutil src = Path('Data/Current') dest = Path('Data/Previous') # Remove existing target directory if it exists if dest.exists(): shutil.rmtree(dest) # Rename source to target src.replace(dest)
You can also use shutil.move(src, dest) instead of src.replace(dest)—both work identically here, since we've already deleted the target.
Method 2: Use Linux's mv -T (Fast, Atomic Operation)
For a more efficient, atomic solution (no recursive delete step), you can leverage Linux's native mv command with the -T flag. This flag forces mv to treat the target as a direct replacement (instead of moving the source into the target directory), which works even if the target is non-empty:
from pathlib import Path import subprocess src = Path('Data/Current') dest = Path('Data/Previous') # Run the Linux mv command with -T to replace the target subprocess.run(['mv', '-T', str(src), str(dest)], check=True)
This method is faster because it skips the recursive deletion of Previous—the system handles the replacement in a single atomic operation, reducing IO overhead and eliminating the gap where the target directory doesn't exist.
Method 3: Merge Directories (Optional, For Partial Overwrites)
If you ever need to preserve non-conflicting files in Previous (like keeping the original X directory), you can manually merge contents instead of full replacement. This is more complex but useful for edge cases:
from pathlib import Path import shutil import os src = Path('Data/Current') dest = Path('Data/Previous') # Iterate over items in source directory for item in src.iterdir(): dest_item = dest / item.name # Remove existing item in target if it exists if dest_item.is_dir(): shutil.rmtree(dest_item) elif dest_item.exists(): os.remove(dest_item) # Move source item to target shutil.move(item, dest) # Delete now-empty source directory src.rmdir()
Final Recommendation
- Use Method 1 if you want a cross-platform, pure Python solution that's easy to read and maintain.
- Use Method 2 if you're strictly on Linux and want the fastest, most atomic operation possible.
内容的提问来源于stack exchange,提问作者Travis Griggs

