结论是python自身无可靠内置同步能力,必须调用rsync(linux/macos)或robocopy(windows)等系统工具,配合subprocess调度、watchdog监听、configparser配置管理及完备错误处理,才能实现稳定跨平台局域网增量同步。

用 rsync + subprocess 做跨平台局域网同步最稳
直接说结论:Python 自身没有内置的、可靠又带增量和断点续传的局域网文件同步能力,硬写 shutil.copytree 或 os.walk + open 会踩一堆坑——比如权限丢失、硬链接崩溃、符号链接循环、大文件卡死、没校验、无法跳过已同步项。真正能落地的方案是调用系统级工具,Linux/macOS 用 rsync,Windows 用 robocopy,Python 只做调度和状态包装。
实操建议:
-
rsync -avz --delete --progress /src/ user@192.168.1.100:/dst/是核心命令,-a保权限时间戳,-v可视化,-z压缩传输,--delete清理目标端多余文件(慎用!先加--dry-run测试) - 用
subprocess.run()调用,捕获stdout和returncode判断成败,别用os.system - Windows 下改用
robocopy C:src \192.168.1.100d$dst /MIR /Z /R:3 /W:5,注意路径用反斜杠、共享路径要提前映射或启用 SMB 签名 - 首次运行前,确保目标机器 SSH(Linux/macOS)或 SMB 共享(Windows)已开启且账号有写权限,否则报错
Connection refused或Access is denied
用 watchdog 监听源目录变更后自动触发同步
手动跑脚本太反人类,真需求是“源文件一改,几秒内同步过去”。Python 的 watchdog 库能监听文件创建、修改、删除事件,但它本身不处理网络传输,只负责“喊一声”。关键在于避免重复触发和误同步。
实操建议:
- 监听时用
patterns=["*.txt", "*.py"]过滤类型,避免临时文件(如.swp、~)触发;用ignore_patterns=["*/__pycache__/*"]排除缓存目录 - 每次事件来临时,启动一个
threading.Timer(2.0, sync_now)延迟执行,防止快速连改 10 个文件触发 10 次 rsync - 同步前检查
if not os.path.exists(target_root),避免目标挂载失败还傻等 - 别监听整个
/home或C:,限定到具体项目目录,否则 CPU 占用飙升、日志刷屏
用 configparser 管理多备份任务配置,避免硬编码 IP 和路径
一台电脑要同步代码、文档、素材三处,每处目标不同、排除规则不同、是否删除也不同——全写死在代码里等于自找维护地狱。必须把配置抽出来,用 INI 文件管理。
实操建议:
- 配置文件
sync.conf写成这样:[project_a] src = /home/user/code dst = user@192.168.1.100:/backup/code exclude = __pycache__, *.log delete = true [docs] src = /home/user/docs dst = 192.168.1.100::docs_module rsync_module = true
- 读取时用
config.getboolean(section, "delete", fallback=False),避免字符串比较出错;用config.get(section, "exclude", fallback="")后再.split(", ") - IP 地址不要写成
192.168.1.100:2222,端口单独配port = 2222,否则解析麻烦且易错 - 密码不能明文存在配置里,SSH 用密钥认证(
ssh-copy-id预置),Windows 共享用凭据管理器存账号
同步失败时记录日志并邮件/桌面通知,别让错误静默消失
局域网不稳定、目标磁盘满、权限突变……这些都会导致 rsync 返回非零码,但如果你没检查 result.returncode,脚本就当成功了,数据实际没过去。
实操建议:
- 每次
subprocess.run()后必须判断:if result.returncode != 0:,然后把result.stdout + result.stderr写进日志文件,带时间戳 - 日志路径用
os.path.join(os.path.dirname(__file__), "sync.log"),别用相对路径"./sync.log",免得 cron 启动时路径错乱 - 失败时调用
subprocess.run(["notify-send", "Sync Failed", f"{section}: {result.stderr[:100]}"])(Linux)或plyer.notification.notify()(跨平台),比只打 print 实用得多 - 别用 SMTP 发邮件——局域网工具没必要外连,真要告警,写个简单 HTTP POST 到内网钉钉机器人 webhook 更快
最难的不是写同步逻辑,而是处理“同步一半断电”“目标空间不足却没报错”“符号链接指向不存在路径”这类边界情况。这些没法靠一个库自动兜底,得靠你对 rsync 错误码的熟悉程度,和每次上线前手动跑 --dry-run 的耐心。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











