应优先使用 rsync 而非 python 自实现文件夹镜像,因其支持增量同步、硬链接、权限/时间戳精确复制及断点续传;python 标准库工具如 shutil.copytree、filecmp.dircmp 或 pathlib+shutil 均存在功能缺失或隐藏陷阱。

用 rsync 命令替代 Python 自实现更可靠
直接写 Python 做文件夹镜像,90% 的情况是重复造轮子且容易出错。系统自带的 rsync 经过几十年打磨,支持增量同步、硬链接保留、权限/时间戳精确复制、断点续传,Python 标准库根本没法比。
实操建议:
- Linux/macOS 直接调用:
subprocess.run(["rsync", "-av --delete", "/src/", "/dst/"])(注意末尾斜杠含义不同) - Windows 可安装
rsync(如通过 Cygwin 或 WSL),或改用robocopy /MIR(原生命令,但不保留 Unix 权限) - 避免用
shutil.copytree:它不支持增量、不跳过未修改文件、无法安全覆盖同名但内容不同的文件
filecmp.dircmp 适合轻量级差异检测,但不能直接同步
如果你非要 Python 控制流程,filecmp.dircmp 是唯一值得考虑的标准库工具,但它只做“比较”,不负责“操作”。常见误用是以为它能自动同步——其实它连删除、覆盖都不做。
使用要点:
-
dircmp.left_only和dircmp.right_only列出单边存在文件,但路径是相对名,需拼接完整路径才能操作 -
dircmp.diff_files只对比文件名和大小,默认不校验内容;要真正判断是否相同,得手动open().read()或用hashlib计算 md5 - 递归比较需自己写循环遍历
dircmp.subdirs,容易漏层或陷入符号链接循环
用 watchdog + rsync 实现实时镜像时要注意触发抖动
监听文件变化再触发同步,看似优雅,实际极易因编辑器临时文件(如 .swp、~ 备份)、IDE 自动生成文件导致高频误触发。
关键规避措施:
- 过滤掉以
.开头、~结尾、含.tmp的路径,用event.is_directory == False and not event.src_path.endswith(('.swp', '~')) - 加 1 秒去抖:收到事件后
time.sleep(1)再检查文件是否最终稳定(尤其对频繁保存的文本编辑场景) - 不要监听整个父目录,而是精确到目标文件夹,否则子目录下
node_modules这类巨量小文件会拖垮监听器
pathlib 搭配 shutil 做单次粗粒度同步有隐藏陷阱
有人用 pathlib.Path.rglob("*") 遍历源目录,再逐个 shutil.copy2 到目标,看似简单,但几个坑很致命:
- 目标目录不存在时
shutil.copy2不自动创建父路径,必须提前dst.parent.mkdir(parents=True, exist_ok=True) - 如果源文件被其他进程占用(如 Excel 正在编辑),
copy2直接抛PermissionError,没重试逻辑就中断 -
shutil.copy2不处理符号链接:默认复制内容而非链接本身;要保留链接得用shutil.copy并设follow_symlinks=False - 删除目标中多余文件需额外遍历,且不能简单
os.remove目录——得用shutil.rmtree,但误删会不可逆
这些细节堆叠起来,一个“简单同步脚本”很快变成 200 行还带 race condition 的脆弱代码。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











