类rsync归档文件更新:能否用UNIX标准归档工具实现增删同步?
好问题!咱们先把核心需求拆明白:你想要的是基于指定文件列表,同步更新归档文件——既把列表里新增/修改的文件加入归档,又把列表里不再存在的文件从归档中移除,对吧?
先聊聊你提到的rsync方案:rsync --include-from=files --exclude-deleted确实是专门为这种同步场景设计的,一步到位,非常省心。那回到你的问题,用zip、tar这些标准UNIX归档工具能不能做到同样的效果?
关于zip:可以通过脚本组合实现,但需要额外步骤
你说的zip -ru@ out < files确实只能处理新增和更新的文件,不会自动删除归档里不在列表中的文件。不过我们可以用一些命令组合来补上“删除”的环节:
# 第一步:更新归档里的新增/修改文件 zip -ru@ out.zip < files.txt # 第二步:找出归档中不在当前文件列表里的文件,批量删除 comm -23 <(unzip -Z1 out.zip | sort) <(sort files.txt) | xargs zip -d out.zip
简单解释一下:
unzip -Z1 out.zip会列出归档里的所有文件名comm -23用来对比两个排序后的列表,找出只存在于归档中的文件zip -d就是删除归档里指定的文件
要注意的是:如果你的文件名包含空格、换行或者特殊字符,这个脚本可能需要额外处理(比如用-0参数配合xargs),而且如果归档很大,遍历和对比的过程会有点耗时。
关于tar:原生没有同步删除的能力,只能删除重建
tar的设计定位是“打包”工具,而非“同步”工具,它没有内置的增量更新并删除旧文件的功能。虽然有增量tar的用法(比如tar -g参数),但那只是基于上次的归档添加新内容,不会移除已经不在列表里的文件,最终归档会越来越臃肿。
所以如果用tar实现你的需求,最直接的办法就是删除旧归档,重新基于文件列表创建新归档:
rm -f out.tar.gz tar -czf out.tar.gz -T files.txt
这个方法简单可靠,但如果归档文件很大、文件列表里的文件很多,每次重建的时间成本会比较高。
总结
如果必须用标准UNIX归档工具:
- zip可以通过脚本组合实现近似的同步效果,但步骤繁琐,不如rsync高效
- tar没有更好的原生方案,只能删除重建
而rsync在这种“基于列表同步归档”的场景下,确实是更合适的选择——它的--exclude-deleted参数就是专门用来处理“移除不在源列表中的文件”这种需求,一步到位,不需要额外的脚本操作。
内容的提问来源于stack exchange,提问作者forthrin

