如何获取实际目录大小(超出du)?

bas*_*ic6 20 linux unix gnu inode du

如何使用 UNIX/Linux 标准工具获取实际目录大小?

替代问题:如何让du向我显示实际目录大小(而不是磁盘使用情况)?

由于人们似乎对术语“大小”有不同的定义:我对“目录大小”的定义是该目录中所有常规文件的总和。

我不关心目录 inode 的大小或文件在相应文件系统上占用的任何大小(块 * 块大小)。一个包含 3 个文件的目录,每个文件 1 个字节,目录大小为 3 个字节(根据我的定义)。

使用 du 计算目录大小似乎不可靠。
例如,mkdir foo && du -b foo报告“4096 foo”,4096 字节而不是 0 字节。对于非常大的目录,报告的目录大小du -hs可能会减少 100 GB (!) 甚至更多(压缩文件系统)。

那么必须使用什么(工具/选项)来获取实际目录大小?

Bri*_*ian 12

某些版本du支持参数--apparent-size显示表观大小而不是磁盘使用情况。所以你的命令是:

du -hs --apparent-size
Run Code Online (Sandbox Code Playgroud)

来自 Ubuntu 12.04 LTS 中 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
Run Code Online (Sandbox Code Playgroud)

  • 不起作用:报告空目录的一些空间 (3认同)
  • 当您比较不同文件系统上的目录时,它会给出明显不同的大小。例如,同一个文件夹在 zfs 文件系统上的表观大小为 290Gb,exFat 为 324Gb。上面的解决方案给出了相同的大小。 (2认同)

jll*_*gre 8

这是一个使用 Unix 标准工具 (POSIX) 显示人类可读目录大小的脚本。

#!/bin/sh
find ${1:-.} -type f -exec ls -lnq {} \+ | awk '
BEGIN {sum=0} # initialization for clarity and safety
function pp() {
  u="+Ki+Mi+Gi+Ti+Pi+Ei";
  split(u,unit,"+");
  v=sum;
  for(i=1;i<7;i++) {
    if(v<1024) break;
    v/=1024;
  }
  printf("%.3f %sB\n", v, unit[i]);
}
{sum+=$5}
END{pp()}'
Run Code Online (Sandbox Code Playgroud)

例如:

$ ds ~        
72.891 GiB
Run Code Online (Sandbox Code Playgroud)


Ser*_*sov 7

假设您du从 GNU coreutils 获得,此命令应该计算目录中任意数量的常规文件的总外观大小,而对文件数量没有任何限制:

find . -type f -print0 | du -scb --files0-from=- | tail -n 1
Run Code Online (Sandbox Code Playgroud)

添加-l选项,du如果里面有一些硬链接文件,并且你想单独计算每个硬链接(默认情况下,du多个硬链接只计算一次)。

与plain最重要的区别du -sb是递归du也计算目录的大小,不同的文件系统报告的目录不同;为避免这种情况,该find命令仅用于将常规文件传递到du. 另一个区别是符号链接被忽略(如果应该计算它们,find应该调整命令)。

此命令也将比plain 消耗更多内存du -sb,因为使用--files0-from=FILEmakedu存储所有已处理文件的设备和inode 编号,与仅记住具有多个硬链接的文件的默认行为相反。(如果该-l选项用于多次计算硬链接,这不是问题,因为存储设备和 inode 编号的唯一原因是跳过已经处理过的硬链接文件。)

如果您想获得总大小的人类可读表示,只需添加-h选项(这有效,因为du仅调用一次并计算总大小本身,与其他一些建议的答案不同):

find . -type f -print0 | du -scbh --files0-from=- | tail -n 1
Run Code Online (Sandbox Code Playgroud)

或(如果您担心 的某些影响-b会被 覆盖-h

find . -type f -print0 | du -sc --apparent-size -h --files0-from=- | tail -n 1
Run Code Online (Sandbox Code Playgroud)