看来,如果您提供多个目录/文件夹参数,du -s
其中某些目录是其他目录的父目录,则参数的顺序取决于是否du
在其输出中显示它们。它还会更改父目录的显示大小。
例如,假设我想查看这 3 个目录的摘要:
/ (actual size: 174G)
/etc
/home
命令#1
✔️我期望看到 3 行输出,因为下面的第一个命令正确地给出了我。
❌ 但是 / 的大小是错误的,因为它已从中减去显示的子目录的大小/
du -sh /home /etc /
79G /home
30M /etc
95G /
命令#2
然而,如果参数的顺序不同,并且父目录在其子目录之前指定,则子目录根本不会显示......
❌3 个目录参数,仅显示 2 个。
❌ 同样, for 的大小是错误的,因为它减去了from/
的大小/home
/
du -sh /home / /etc
79G /home
95G /
命令#3
❌3 个目录参数,仅显示 1 个。
✔️ /
显示正确的总大小。
du -sh / /home /etc
174G /
问题
为什么这有关系?我想这可能与它内部计数的方式有关,而不是重新计数,但令人意外的是,这些命令会产生完全不同的结果。
有没有办法
du
始终给我预期的 3 行输出,以及父目录的正确总大小(即/
上面的 174G)...无论给出的参数的顺序如何?即预期输出:79G /home 30M /etc 174G /
我希望这是高效的,即它应该只递归遍历最高级别的目录一次,并为任何显示的子目录重新使用预先计算的信息。如果我改为使用find
+xargs
来运行多个单独的du
命令,那么它将在每个级别的子级上一次又一次地进行大量的重新扫描。
答案1
du
报告磁盘使用情况。
它只会对每个文件的磁盘使用情况进行一次计数,即使这些文件是通过两个不同的名称(包括通过硬链接)找到的。
如果a
和b
是同一文件的硬链接,du a b
则仅报告a
,du b a
仅b
在处理第二个文件时报告,du
意识到它已被考虑在内。
同样du / /etc
,在降序时找到的所有文件/etc
在处理时都已经被考虑在内/
,因此没有什么可以报告的/etc
。
您会发现,在您的情况下,报告的磁盘使用量总和始终相同且一致:174G,因为这是其中所有文件使用的磁盘空间。
通过 GNU 实现,您可以使用/选项du
禁用重复数据删除。但是这些目录的累积磁盘使用情况将不再正确(即使是单个目录,如果其中存在硬链接)。-l
--count-links
如果您想获得 的累计磁盘使用量/
,/home
并且/etc
彼此独立,请运行 3 次调用du
:
du -s /
du -s /home
du -s /etc
或者在zsh
:
for d (/ /home /etc) du -s $d
无论如何,请注意,如果其中有文件在/home
其外部硬链接,则删除/home
及其所有内容不一定会回收与 报告的一样多的空间du
。
答案2
该du
命令竭尽全力避免对文件或目录进行多次计数。这是来自POSIX 定义其中指出,
在一个文件操作数下多次出现且链接计数大于 1 的文件应仅针对一个条目进行计数和写入。链接计数不大于 1 的文件是只计数和写入一次,还是每次出现都计数和写入,这是由实现定义的。一个文件操作数下出现的文件是否计入其他文件操作数是由实现定义的。
对于 GNU du
,使用命令du -sh /home /
,确定 所使用的空间/home
,然后确定 所使用的空间/
不包括已经访问过的地方du
。
如果您想要三个目录层次结构示例的完全独立的值,您将需要调用du
三次:
du -sh /
du -sh /home
du -sh /etc