tar --listed-incremental 是否包含每个增量中的所有目录?

tar --listed-incremental 是否包含每个增量中的所有目录?

给定一个包含文件的树结构,说:

source
|-- bar
|   +-- three.txt
|-- baz
|   +-- four.txt
+-- foo
    |-- one.txt
    +-- two.txt

如果我做

tar czvf dest/archive-1.tgz --listed-incremental dest/archive.snar source/*

这将创建一个.tgz包含所有当前文件和文件夹的文件,正如我所期望的:

source/bar/
source/baz/
source/foo/
source/bar/three.txt
source/baz/four.txt
source/foo/one.txt
source/foo/two.txt

如果我立即这样做:

tar czvf dest/archive-2.tgz --listed-incremental dest/archive.snar source/*

这似乎创建了.tgz包含当前目录的所有子文件夹但没有文件的文件:

source/bar/
source/baz/
source/foo/

这不是我想要的。在像这样的玩具示例中,情况还不算太糟,但在大型文件夹结构中,很难判断 .tgz 本质上是空的。噪音很大。理想情况下,它会tar告诉我没有更新的文件并以错误代码退出,但即使它生成了一个空的 tar,这也比包含许多空文件夹的存档要好(对我来说,在这种情况下)。

有什么方法可以让它tar --listed-incremental按照我想要的方式运行吗?我搜索了几次以寻找解决方案,但没有找到太多。

我可能最终会停止使用--listed-incremental,而是做一些工作来find汇编文件列表,但如果有办法实现我想要的效果,那么工作量就会大得多--listed-incremental。有什么建议吗?

答案1

手册页提到:

从增量备份中提取时,GNU tar 会尝试恢复创建存档时文件系统的准确状态。具体来说,它将删除文件系统中那些在创建存档时目录中不存在的文件。

为了实现这一点,他们要么需要在档案中有一个包含所有已删除文件列表的特殊文件,要么需要一份所有目录 inode 的副本,以便删除相关文件。为了与档案格式保持一致,对他们来说,只包含目录可能​​更简洁,而不是用额外的文件让事情变得复杂。

经过编辑试图澄清答案:

示例 1:扩展原始示例...

步骤 1:删除其中一个现有文件,并创建增量存档

$ rm source/foo/two.txt
rm: remove regular empty file `source/foo/two.txt'? y

$ tar czvf dest/archive-3.tgz --listed-incremental dest/archive.snar source/*
source/bar/
source/baz/
source/foo/

步骤 2:在 foo 中重新创建先前的文件

$ touch source/foo/two.txt

步骤 3:提取增量存档,这将删除我们刚刚创建的文件(它知道原始存档中缺少此文件,因为存档中包含的目录条目 source/foo/ 在其“目录”中没有提及它)

$ tar xvfz dest/archive-3.tgz --listed-incremental dest/archive.snar
source/bar/
source/baz/
source/foo/
tar: Deleting `source/foo/two.txt'

示例 2:包括顶级目录,如果增量存档中缺少 foo 目录(及其文件),则会将其删除。

步骤 1:使用“source”而不是“source/*”创建初始档案

$ tar czvf dest/archive-1.tgz --listed-incremental dest/archive.snar source
source/
source/bar/
source/baz/
source/foo/
source/bar/three.txt
source/baz/four.txt
source/foo/one.txt
source/foo/two.txt

第 2 步:删除 foo 目录并创建不包含对 foo 的引用的增量存档。

$ rm -rf source/foo
$ tar czvf dest/archive-2.tgz --listed-incremental dest/archive.snar source
source/
source/bar/
source/baz/

步骤 3:重新创建 foo 目录

$ mkdir source/foo
$ touch source/foo/one.txt
$ touch source/foo/two.txt

步骤 4:提取档案(此时 foo 将被删除,因为它没有出现在“source/”条目的“目录”中)。

$ tar xzvf dest/archive-2.tgz --listed-incremental dest/archive.snar source
source/
tar: Deleting `source/foo'
source/bar/
source/baz/

相关内容