获取目录的大小(包括其所有内容),无论磁盘使用情况如何

获取目录的大小(包括其所有内容),无论磁盘使用情况如何

一般问题

假设两个内容相同的目录存储在不同的设备上。有没有一种方法可以计算目录的大小并始终获得完全相同的数字?换句话说,是否存在目录的“实际大小”,无论其存储在何处?

实际例子

我使用在两个存储设备之间传输目录rsync -ahP /dir1/ /dir2/。传输顺利完成后,我使用 .检查了每个设备上的目录大小du -s --apparent-size。对于某些目录,我在两台设备上得到了完全相同的编号,但并非所有目录都如此。

具体问题

是否有可能rsync使用所选选项没有生成目录的精确副本?如果是的话,有没有办法获得精确的副本?

无论存储设备如何,所使用的du命令是否都不会给出目录的“实际大小”。如果是的话,有没有办法计算这样的尺寸?

答案1

请注意du,即使 GNU 的选项也将包括所有类型文件的--apparent-size表观大小(如 所报告),包括lstat()常规文件,设备,符号链接,先进先出,目录。与许多其他实现一样, GNUdu会尝试不对同一文件进行多次计数(例如当同一文件有多个硬链接时)。

在这里,由于您没有将-H选项传递给rsync,因此不会保留硬链接,因此du如果源中存在硬链接,则排除 的帐户中的重复项会导致差异。

类型文件的表观大小目录确实代表了它的实际大小数据:文件名列表以及有关在何处查找它们的信息,但该列表的格式和大小取决于文件系统的类型、其配置方式以及目录的填充方式。

对于rsync不传输任何数据的设备文件、fifo、套接字,某些系统(如 Linux)总是返回 0 作为表观大小,有些系统将返回可以从中读取的数据量(例如,对于块设备文件) ,它可能是相应存储的大小)。

所以在这里,你能做的最好的可能就是计算表观大小的总和常规的符号链接文件从一个系统到另一个系统都是一致的。

你可以使用 GNU 来做到这一点find

find . -type f,l -printf '%s\n' | awk '{s+=$0}; END{print s}'

如果您在源和目的地上发现相同的号码,则表明rsync可能已成功转移所有数据(常规文件的内容和符号链接(其目标路径))。它可能无法成功传输所有元数据,例如扩展属性、ACL(由于您没有传递-X-A选项,因此您无论如何都不会保留这两个元数据)、文件名、空文件...

作为目录数据量的一致表示(假设没有编码问题1),您可以使用find . | wc -c(所有文件路径长度的总和+ 1)。

您还可以使用(dry-run)和(verbose)重新运行相同的rsync命令来检查是否缺少内容,也许添加一个来检查目标而不是源上的文件。-n-v--delete


严格来说,如果对文件名进行一些转换,例如在某些非 ASCII 字符的字符编码转换的情况下,尤其是涉及非 Unix 或 macOS 文件系统时,符号链接大小可能会有所不同

答案2

Rsync 和其他工具不会精确复制目录。他们可能会也可能不会准确地复制稀疏文件。这是不是一般来说需要关心的事情。

考虑以下 bash 示例。

 mkdir -p /tmp/demo/a
 cd /tmp/demo/a
 touch {1..10000}
 ls -ld

这将创建 10,000 个文件并列出保存它们的目录的大小。在我的系统上,我得到一个大小为 155648 字节的目录。现在取出 9,000 个并再次检查尺寸。

 rm ????
 ls -ld

我的目录大小保持不变,为 155648 字节。现在制作一个副本,我在这里使用,cp但它可以是复制文件的rsync或任何其他东西cpio

 cd ..
 cp -r a b
 ls -l

对我来说,该b目录只有 20,480 字节,即小 135,168 字节。这是因为该a目录中有空间可容纳已删除的文件 3141 的条目,但b没有分配该空间。

相关内容