为什么`du`命令的输出结果经常与`du -b`命令不同?

49
为什么du命令的输出结果通常与du -b的结果如此不同?-b--apparent-size --block-size=1的缩写。只使用--apparent-size大多数情况下会得到相同的结果,但是--block-size=1似乎能够解决这个问题。我想知道这时输出是否正确,以及哪些数字才是我想要的?(例如,如果将文件复制到另一个存储设备中,实际的文件大小是多少)

11
为什么会有负评?这看起来是一个非常好的问题。如果您要给一个问题或答案负评,请有礼貌地发表评论,以便每个人都能学到一些东西。匿名的负评是可能被浪费的教学机会。 - Pete Wilson
1
@Pete:可能是因为这在StackOverflow上与主题无关。希望会有一些声望较高的用户注意到。 - Ken Bloom
与服务器故障相关的问题:https://serverfault.com/questions/290088/what-is-the-difference-between-du-h-and-ls-lh - GDP2
5个回答

45

表面大小是应用程序认为文件中包含的字节数。如果您决定通过FTP或HTTP发送该文件,它是将要传输的数据量(不包括协议头)。它也是cat theFile | wc -c的结果,以及如果您使用mmap加载整个文件时所占用的地址空间。

磁盘使用量是指由于文件占用该空间而无法用于其他用途的空间总量。

在大多数情况下,表面大小比磁盘使用量小,因为磁盘使用量计算了文件最后(部分)块的完整大小,而表面大小仅计算该最后块中存在的数据量。但是,当您有一个稀疏文件时,表面大小会变大(当您在文件结尾之外寻址并在那里写入内容时就会创建稀疏文件--操作系统不会创建许多填充零的块--它只为您决定写入的文件部分创建一个块)。


谢谢!这是一个详细的解释。那么为什么我需要使用 --block-size=1 才能得到与 wc -c theFile 相同的输出(避免了 cat 进程)。看起来只有当我指定 -h、-k、-m、-B1 等选项时,du 才会输出正确的字节数?但也许这真的是另一个问题?默认情况下,du 输出块使用量而不是字节使用量? - knittl

8

最小块粒度示例

我们玩一下,看看发生了什么。

mount告诉我我在挂载在/的ext4分区上。

我用以下命令找到其块大小:

stat -fc %s .

这会给出:

4096

现在让我们创建一些文件,它们的大小分别为1 4095 4096 4097,并使用--block-size=1(等同于-b)进行测试:
#!/usr/bin/env bash
for size in 1 4095 4096 4097; do
  dd if=/dev/zero of=f bs=1 count="${size}" status=none
  echo "size     ${size}"
  echo "real     $(du --block-size=1 f)"
  echo "apparent $(du --block-size=1 --apparent-size f)"
  echo
done

结果如下:

size     1
real     4096   f
apparent 1      f

size     4095
real     4096   f
apparent 4095   f

size     4096
real     4096   f
apparent 4096   f

size     4097
real     8192   f
apparent 4097   f

因此,我们可以看到任何小于或等于 4096 的东西实际上占用了 4096 个字节。

然后,一旦我们超过 4097,它就会增加到 8192,即为 2 * 4096

很明显,磁盘始终以 4096 字节的块边界存储数据。

那么对于稀疏文件会发生什么呢?

我没有调查是什么确切的表示方式,但很明显 --apparent 考虑了这一点。

这可能导致表面大小大于实际磁盘使用量。

例如:

dd seek=1G if=/dev/zero of=f bs=1 count=1 status=none
du --block-size=1 f
du --block-size=1 --apparent f

提供:

8192    f
1073741825      f

相关: 如何测试是否支持稀疏文件

如果我想存储一堆小文件怎么办?

有以下几种可能:

参考文献:

在Ubuntu 16.04中测试通过。


1
这是一个非常好的答案 - 通过实际命令(我称之为“实验”)来说明要点,使得答案和基本原理非常清晰。+1 - bballdave025
1
@bballdave025 谢谢!是的,我对实验着迷,相关评论在这里 - Ciro Santilli OurBigBook.com
1
这是一篇很棒的文章!我会把它存档(我会把数据保存在那里,因为我不记得它了:)你的评论让我想起我的两个朋友和我一起上本科物理课程,并在研究生期间保持联系的故事。其中一个朋友总是说,“从第一原理推导,何必去记忆!”这一直是我们的主题之一。如果你无法推导出来,就去做实验吧!(噢,我们也常说,“是时候使用推土机方法了!”) - bballdave025
@bballdave025 啊,你学了物理,太棒了!我人生中最大的遗憾之一就是没有去学它,现在如果有一个好的光学台供我使用,我会不惜一切代价去得到它...所以我现在只能用像“du”这样的东西进行实验! - Ciro Santilli OurBigBook.com

3
比较(例如)du -bmdu -m-b设置--apparent-size --block-size=1,但是接着m会覆盖块大小为1M
对于-bh-h也类似: -bh表示--apparent-size --block-size=1 --human-readable,再次h会覆盖该块大小。

如果仔细阅读问题,那么这就是正确的答案。重点在于 --block-size 默认情况下通常不是 1(即没有选项的 du),而是1024或512。--apparent-size-b 的无关副作用。 - norio
谢谢这个提示,这比“--apparent-size”要短得多。 - Arnie97

2
文件和文件夹有它们的真实大小和磁盘上的大小。
- --apparent-size 是文件或文件夹的真实大小。 - 磁盘上的大小是文件或文件夹在磁盘上占用的字节数。使用 du 命令时同样如此。
如果你发现 apparent-size 几乎总是比磁盘使用量高几个数量级,那么这意味着你有很多“稀疏”文件、内部碎片或间接块的文件。

1

因为默认情况下du会给出磁盘使用量,这与文件大小相同或更大。如--apparent-size所述。

print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be
larger due to holes in (`sparse') files, internal fragmentation, indirect blocks, and the like

那么'apparent-size'到底是什么?我遇到的情况恰好相反:apparent-size几乎总是比磁盘使用量高几个数量级。 - knittl
1
实际上,默认情况下,启用压缩的分区也可以更小。 - ARA1307

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接