我需要获取终端中目录的大小以进行签名。我正在使用以下命令:
du -s /path/to/dir
我将结果乘以传统的 UNIX 块大小(512 字节)并获得实际目录大小(以字节为单位)。然而,Finder 的“获取信息”对话框窗口显示的大小略小于使用终端命令计算的大小。而且它似乎可以在任何文件夹/捆绑包上重现。我缺少什么?
答案1
通常,du
显示有关的信息磁盘使用情况(这就是它的名字的由来)。请记住
disk usage != sum of file sizes
因为每个文件占用一定的空间块在文件系统上(参见man mkfs.ext2
示例)。这意味着只有在极少数情况下,文件的磁盘使用量等于其实际大小 - 为此,该大小必须恰好是块大小的倍数。
将文件系统块视为包含文件部分的盒子 - 每个块只能包含一个文件的一部分。
对于 GNU 版本du
,请查看该--apparent-size
选项。
当有一些稀疏文件在文件系统上!
答案2
关于 Mac OS X 和 Finder(在 Snow Leopard 中,版本 10.6.8)我注意到以下内容。
- 我使用下面的代码(在(1)中)获取路径(文件或文件夹)的 Finder“量化”数字的字节计数
bash
。 - Finder“信息”窗口和窗格以十进制(基数 10、1000)字节显示“量化”(例如以 KB 为单位的千)数字,而不是二进制(基数 2、1024)字节,因此我通过除以来“量化” 1000 并增加单位(字节)前缀“量词”(量值)并进行一些奇怪的“离调”舍入。 (我的完整代码充满了注释掉的开发代码,并分为多个文件(和语言),因此很难共享。)
据我所知,我的“量化”数字与 Finder 中的“量化”数字相同。 - 另外,除了代码之外,我想说的是,我
BLOCKSIZE
的 shell 中没有设置(并且从未设置过任何)环境变量,但我测试了(现在稍微)两个版本,并且默认值$BLOCKSIZE
给出了相同的值。
#!/usr/bin/env bash
#tab-width:4
du -s "${@:-.}" |awk '{u+=$1}END{ print u*'${BLOCKSIZE:-0512}' }'||exit $? #macosx (xnu)
# gdu -sB${BLOCKSIZE:-4096} "${@:-.}" |awk '{u+=$1}END{ print u*'${BLOCKSIZE:-4096}' }'||exit $? #macports gnu
- 我无法匹配的未量化数字。
我唯一能说的是,我通过仅计算文件来接近(因此排除目录〜'文件系统元索引/标题'〜数据),并且我得到的最接近的是以下内容。
#!/usr/bin/env bash
#tab-width:4
for a;do find "$a" -type f -print0|xargs -0 stat -f %z |awk '{u+=$1}END{ print u }'||exit $?;done #macosx (xnu)
# for a;do find "$a" -type f -print0|xargs -0 gstat -c %s |awk '{u+=$1}END{ print u }'||exit $?;done #macports gnu
- (xnu)
du
(1) 和 (gnu)gdu
(1) 似乎都不计算扩展属性 (xattr
)
然后我必须只是双关语“跑完这条路,做一下数学”
这次平静下来,真正的晚安。
答案3
目录中所有文件的总和:
操作系统:find dir ! -type d -print0 | xargs -0 stat -f '%z' | awk '{sum += $1} END{print sum}'
Linux:find dir ! -type d -printf "%s\n" | awk '{sum += $1} END{print sum}'
答案4
在我的 Ubuntu 系统上,使用 ext4, du -b file
给出实际文件的字节大小,并du -b dir
给出文件的字节大小 + 目录开销,在我的情况下,开销是 4096 字节的倍数..
此开销随着文件数量的增加而增加。
注意:即使文件被删除,目录开销仍保持在文件被删除之前的较高水平。
我还没有尝试重新启动,看看它是否恢复,但无论哪种情况,这都意味着目录大小根据历史情况而变化。
统计每个文件的大小可能是准确计算总大小的最佳选择文件尺寸。
以下脚本计算所有文件大小的总和(以字节为单位)。
对于 OS X,如果您没有-b
“du”选项,则可以使用stat
。(如果有的话:)... 注释行显示了 Ubuntu 的stat
替代方案du -b
;
unset total
while IFS= read -r -d $'\0' rf; do
# (( total += $(stat "$rf" | sed -nre 's/^ Size: ([0-9]+).*/\1/p') ))
(( total += $(du -b "$rf" | cut -f 1) ))
done < <(find . -type f -name '*' -print0)
echo $total