我正在某个巨大的目录上执行正常的
du
。这可能需要很长时间,因为存储也是连接网络的。
我希望在流程结束之前查看进度,以便我可以估计正在发生的情况。在任何给定时间,我都希望看到已收集的磁盘使用量总和,因为
du
对其进行了计数。我发现 du
没有提供此功能的选项。我错过了什么?有没有简单的方法可以实现这一目标?
我想象了这样的事情:
du -ba . | { s=0; while read a b; do ((s+=a)); echo $s; done; }
这将对输出进行求和,但当然这也会对累积的目录大小进行求和(有效地乘以计数的大小)。我发现没有选项可以在输出中仅提及 files 。另一方面,使用
find -type f -printf "%s %p\n"
会多次计算硬链接。
是否有任何典型的工具可以实现我想要的目标或对所呈现的脚本进行简单的修复?目前我正在考虑为此编写一个 Python 脚本,但感觉可能有点过分了。
我想出了一个简短的 bash 语句来解决我的问题。它不如正确使用
du
那么好,但它提供了进度信息,并且不会将硬链接计数两次。
我在这里将其写成一行,然后展开以使其更清晰:
find -type f -printf "%s %i %p\n" | { sum=0; declare -A inodes; while read size inode path; do [ "${inodes[$inode]}" != 1 ] && { inodes[$inode]=1; ((sum+=size)); echo "$sum $size $path"; }; done; }
同样格式精美:
find -type f -printf "%s %i %p\n" | {
sum=0
declare -A inodes
while read size inode path
do
[ "${inodes[$inode]}" != 1 ] && {
inodes[$inode]=1
((sum+=size))
echo "$sum $size $path"
}
done
}
我认为,为了从
du
实用程序与任何自定义脚本的性能中获益,人们可以:
tar -xf coreutils-8.30.tar.xz && cd coreutils-8.30
./configure --prefix=/custom/location/of/modified/coreutils
./src/du.c
行后添加 666
语句 print_size (&tot_dui, _("total"));
process_file
函数的结尾看起来像:
if ((IS_DIR_TYPE (info) && level <= max_depth)
|| (opt_all && level <= max_depth)
|| level == 0)
{
/* Print or elide this entry according to the --threshold option. */
uintmax_t v = opt_inodes ? dui_to_print.inodes : dui_to_print.size;
if (opt_threshold < 0
? v <= -opt_threshold
: v >= opt_threshold)
print_size (&dui_to_print, file);
print_size (&tot_dui, _("total")); /* extra statement */
}
return ok;
make install
这将使修改后的
du
报告每个文件后的总大小,即输出可能如下所示:
129K ./bin/dirname
33M total
132K ./bin/uname
33M total
207K ./bin/sha1sum
33M total
156K ./bin/truncate
33M total
311K ./bin/pr
34M total
172K ./bin/printf
34M total
138K ./bin/pathchk
34M total
也许下面的命令会给你一个前进的提示
ls -laR | awk '{ total += $6;if(FNR%1000 == 0)print total;}; END { print total }'
在 awk 语句中,您可以通过各种条件来检查它是目录还是链接。
并且
FNR%1000
将打印它读取的每一百行的大小进度。您可以使用 ls
代替
find