rsync 的 --delete-excluded 到底会删除什么?
rsync --delete-excluded 会把"被 --exclude 排除、但已存在于目标目录"的文件删除,让排除规则从源镜像到目标。威力大、风险也大,用错会误删数据。本文讲清行为、示例与安全用法。
一句话:--delete-excluded 使普通排除规则不再保护目标端的匹配文件,并启用删除;实际删除时机取决于删除算法——相当于把源的排除清单"镜像"到目标。
以下针对上游 rsync;先检查 rsync --version,其他实现(如 openrsync)可能行为不同,应使用实际执行文件在临时目录验证。
行为拆解
配合普通 --exclude 使用时,行为包括(不是固定执行顺序):
- 按排除规则跳过源中匹配的文件(不传输);
- 正常同步其余文件到目标;
--delete-excluded生效:在正在同步的目录树中,被排除的目标项不再受普通排除规则保护,可能被删除;显式接收端保护规则仍可阻止删除。
rsync -av --delete-excluded --exclude='*.log' source/ destination/
效果:本例同步范围内的目标日志文件可被删除,即使它们原本只在目标端存在;其他源端不存在的目标项也可能被删,并非只清理日志后缀。
与之对比:--delete 删除的是"目标有而源没有"的文件;--delete-excluded 在此基础上把"被排除的"也纳入删除范围。
危险警告
这是 rsync 最容易造成误删的选项之一。经典事故:排除规则写得比预期宽(如 --exclude='cache' 匹配到目标里一个同名的业务目录),目标数据被静默清除。
安全用法三步:
# 1. 先空跑,看清楚它要删什么
rsync -avn --delete-excluded --exclude='*.log' source/ destination/
# 2. 确认输出中 deleting 的文件确实可删
# 3. 去掉 -n 正式执行
排除模式尽量写具体路径(--exclude='/cache/' 而不是 --exclude='cache'),缩小匹配面。
常见问题(FAQ)
Q:--delete 和 --delete-excluded 的区别?
--delete 只删"目标比源多出来且未被排除"的文件;--delete-excluded 额外删除"目标里命中排除规则"的文件。上游 rsync 中后者隐含启用删除,但显式接收端保护规则仍生效。
Q:只想清理目标里的日志文件,不想动其他排除项?
仅拆成多个 --exclude 并不能恢复目标保护。可用明确的接收端保护规则(如 --filter='P /keep.log'),先验证规则顺序与目录范围;若只是清理旧日志,单独的保留策略通常更容易审查,应先列出候选文件再删除。
Q:空跑(-n)显示的删除列表可信吗?
空跑只预测检查当时的文件状态;随后新增、删除或变动的文件可能改变实际结果。应核对源/目标路径、规则与删除清单,并为重要数据保留可恢复副本。