rsync --delete 发布时保留目标独有的 .well-known 目录
rsync 删除目标多余文件时,可用排除规则保留独立目录;若带 delete-excluded,需显式区分接收端保护与发送端隐藏,先预演再执行。
发布静态文件时,源目录里没有服务器上的 .well-known/,rsync --delete 因而计划将它删除。把这个目录改成不可写,可能只会让同步报权限错误,并没有表达“它由服务器单独维护”的部署规则。
当目标同时包含发布产物和独立维护的文件时,需要给后者设置排除或接收端保护规则。以下限定 rsync 的目录同步,示例使用本地路径展示规则;远程同步也要核对两端版本、完整参数和接收目录,不能照抄占位路径执行。
普通排除规则也会保护目标
若 .well-known/ 完全由目标端管理,源端同名目录也不应发布,可以先预演:
rsync -a --dry-run --itemize-changes --delete \
--exclude='/.well-known/' -- \
/srv/site-output/ /srv/site-live/
/srv/site-output/ 是已核实的源目录,/srv/site-live/ 是目标目录,均需替换为实际路径。源路径末尾的 / 表示同步它的内容,所以规则开头的 / 锚定这次传输的根,匹配目标根下的 .well-known/。末尾 / 限定目录;不要把预期目录为文件或符号链接的异常情况当作已受相同规则保护。
普通 --exclude 默认有两侧作用:发送端不把匹配项放入传输清单,接收端在删除阶段保护匹配项。因此,这条规则不仅不发送同名目录,也会保留目标现有目录及其内容。
这个默认行为有条件。如果命令还带着 --delete-excluded,未限定作用端的排除规则会成为发送端规则,不再保护目标删除。只添加一条 exclude,却忽略发布脚本里的这个选项,仍然可能删掉需要保留的内容。
需要保留删除排除项的策略时,显式保护接收端
有些部署确实要删除其他被排除的旧文件,不能全局取消 --delete-excluded。此时可明确为独立目录分别设置接收端保护与发送端隐藏:
rsync -a --dry-run --itemize-changes --delete-excluded \
--filter='P /.well-known/***' \
--filter='H /.well-known/***' -- \
/srv/site-output/ /srv/site-live/
P 是 protect,保护匹配项免于删除;H 是 hide,不把发送端匹配项放入传输清单。/*** 同时匹配该目录和它的全部内容。这里的 --delete-excluded 已隐含删除处理,示例没有再重复加 --delete。
两条规则分别表达不同目的。只写 P 时,目标文件虽然受删除保护,但源端若有同名文件,仍可能更新它;如果目录必须由目标独占管理,就还需要 H。反过来,只写 H 不会保护目标。
过滤规则按顺序匹配。将这两条放在可能先命中的广泛规则之前,并检查脚本是否还加载了过滤文件、清空规则或其他 include/exclude。不能只审查终端里新增的两行,而忽略原有规则集合。
不需要 --delete-excluded 的部署应优先保留前一种简单排除写法,不要为使用保护规则而主动扩大删除范围。这里也不要求把 --delete 一律替换成 --delete-after;删除时机与本例的命令行保护规则是不同设置。
预演必须同时检查保留项与应删项
在与生产目录结构相同的测试副本上核对:目标独有的 .well-known/ 及其内容不应出现 *deleting;另一个明确允许删除、源端不存在的普通旧文件应出现在删除计划中。这样才能确认例外生效,同时没有意外关闭整个清理策略。
还要在源副本放入一个同名目录中的测试文件,确认独占管理方案没有安排覆盖目标同名文件。只看“没有删除”无法验证更新隔离;不要用真实证书验证文件或业务数据做试验。
--dry-run 不进行实际变更,--itemize-changes 显示计划,包括 *deleting 记录。它也不会证明真实写入权限、磁盘空间和所有系统调用都能成功;源或目标在预演后变化,正式结果也可能不同。保留完整输出与退出状态,不要只过滤出关心的目录就忽略其他错误。
正式执行前保留可恢复的目标
正式同步前保存目标数据、权限及当前发布脚本,确认备份位于这次同步范围之外且能够恢复。重新核对源目录不是意外的空目录,目标路径没有写反,保护规则与经过审核的预演完全一致。
只有这些条件满足后,才从已核验的命令中移除 --dry-run 执行。不要同时修改过滤范围或追加 --ignore-errors。同步结束后核对独立目录内容、发布产物和退出状态,必要时在数据稳定的条件下再预演查看残留差异。
如果独立目录已经被删除,后来补上保护规则只会影响后续同步,不会找回文件。应先停止有问题的发布流程,从同步前的备份恢复对应目录及属性,再修正规则。取消 --delete 也不是撤销删除的办法。


