You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅用rsync与POSIX shell脚本能否实现多客户端通过中心服务器同步?

仅用rsync + POSIX Shell实现多客户端与服务器的双向同步(含增删改)

你碰到的这个问题刚好是rsync单向同步特性带来的经典坑,但别担心——只用rsync加几行POSIX Shell脚本完全能搞定。核心思路是把同步拆成「拉取更新」「推送修改」「双向删同步」三个阶段,避开--delete选项的方向性冲突。下面是可直接落地的方案:


分步实现脚本

假设你的服务器路径是user@server:/main-storage/,客户端本地副本路径是./local-copy/,脚本可以这么写:

1. 先拉取服务器的更新到客户端(保留本地新增)

这一步只同步服务器的新增/修改文件,绝不删除客户端自己加的文件,避免客户端刚新增的内容被冲掉:

rsync -avz --no-delete user@server:/main-storage/ ./local-copy/
  • --no-delete:核心参数,禁用“删除客户端有但服务器没有的文件”的逻辑
  • -avz:归档模式(保留权限、时间戳等元数据)+ 详细输出 + 压缩传输,是rsync同步的标准组合

2. 推送客户端的新增/修改到服务器

把客户端这边的新文件、改好的文件推送到服务器,同样不碰删除操作:

rsync -avz ./local-copy/ user@server:/main-storage/

这一步之后,服务器和客户端的「新增/修改内容」就完全一致了,接下来只需要处理两边的删除差异。

3. 同步双向的删除操作(关键步骤)

这一步要解决两个问题:客户端删了的文件要同步到服务器,服务器被其他客户端删了的文件要同步到客户端。我们用文件列表对比来精准定位要删的内容:

3.1 生成两边的文件列表(相对路径)

用POSIX兼容的find命令生成两边的文件路径(只保留相对于同步目录的路径,方便对比):

# 生成客户端本地文件列表
find ./local-copy/ -type f -printf "%P\n" | sort > client-files.txt

# 生成服务器端文件列表(通过ssh远程执行)
ssh user@server "find /main-storage/ -type f -printf '%P\n' | sort" > server-files.txt

如果你的系统find不支持-printf(比如某些极简嵌入式系统),可以替换成:

# 客户端列表替代写法
find ./local-copy/ -type f | sed 's|^./local-copy/||' | sort > client-files.txt
# 服务器列表替代写法
ssh user@server "find /main-storage/ -type f | sed 's|^/main-storage/||' | sort" > server-files.txt

3.2 找出需要删除的文件

用comm命令对比两个列表,分别找出两边的冗余文件:

# 服务器有但客户端没有的文件 → 需要从服务器删除(客户端已删)
comm -23 server-files.txt client-files.txt > delete-from-server.txt

# 客户端有但服务器没有的文件 → 需要从客户端删除(其他客户端已删)
comm -13 server-files.txt client-files.txt > delete-from-client.txt

3.3 执行删除

只在有需要删除的文件时执行操作,避免空命令报错:

# 删除服务器上的冗余文件
if [ -s delete-from-server.txt ]; then
    ssh user@server "cd /main-storage/ && xargs rm -f < /dev/stdin" < delete-from-server.txt
fi

# 删除客户端上的冗余文件
if [ -s delete-from-client.txt ]; then
    cd ./local-copy/ && xargs rm -f < ../delete-from-client.txt
fi

3.4 清理临时文件

rm -f client-files.txt server-files.txt delete-from-server.txt delete-from-client.txt

方案说明与注意事项

  • 为什么这个方案能解决问题?:我们把「增改同步」和「删除同步」完全分开,先确保两边的新增/修改内容完全对齐,再通过精准的文件列表对比来处理删除,彻底避开了rsync --delete的方向性矛盾——不会出现先拉取删本地新增,或者先推送删服务器上其他客户端内容的问题。
  • 处理目录删除:上面的脚本只处理了文件,如果需要同步目录的删除,把find命令里的-type f去掉即可,删除时把rm -f改成rm -rf(注意:删除目录风险更高,建议先在测试环境验证)。
  • 并发同步的小问题:如果多个客户端同时执行同步,可能会出现短暂的不一致,但因为是定期执行,下一次同步会自动修正,不会有永久冲突。
  • 简化版风险提示:有人会想到用rsync --delete-after先拉再推,但这种方式会删除客户端的新增文件,完全不适合你的场景,千万别用。

内容的提问来源于stack exchange,提问作者Mecki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:33:16