如何仅对未在其他位置进行硬链接的文件占用的空间进行“ du”处理?


14

采用rsync --link-dest了节省空间的快照,我怎么能弄清楚我多少空间实际保存?或更笼统:

如何仅考虑未在目录结构以外的地方进行硬链接的文件,从而计算出目录使用了多少空间?提出不同的问题:删除该目录后实际上将释放多少空间?(du -hs会说谎。可能包含硬链接本身所需的空间)


2
默认情况下,du除非您使用-l/ --count-links选项,否则GNU 仅对文件大小进行一次计数,即使它们是硬链接也是如此。您du在整个树上运行了两次,使用和不使用该选项,大小之间的差异应该是您在所有目录上节省了多少空间。
2012年

Answers:


9

假设没有内部硬链接(也就是说,每个具有多于1个硬链接的文件都是从树外部链接的),则可以执行以下操作:

find . -links -2 -print0 | du -c --files0-from=-

编辑这是我在评论中勾勒出的内容。只有没有du; @StephaneChazelas无需引起注意du。最后解释。

( find . -type d -printf '%k + ' ; \
  find . \! -type d -printf '%n\t%i\t%k\n' | \
    sort | uniq -c                         | \
    awk '$1 >= $2 { print $4 " +\\" }' ; \
  echo 0 ) | bc

我们要做的是创建一个字符串,其中包含每个相关文件的磁盘使用情况(以KB为单位),并用加号分隔。然后,我们将大量食物添加到bc

第一次find调用对目录执行此操作。

第二个find打印链接计数,索引节点和磁盘使用情况。我们通过该列表sort | uniq -c来获得列表(树中的出现次数,链接数,索引节点,磁盘使用情况)。

我们通过传递列表awk,并且,如果第一个字段(出现的次数)大于或等于第二个字段(出现的硬链接数),表示没有树外链接到此文件的链接,则打印第四个字段(磁盘使用情况),并带有加号和反斜杠。

最后,我们输出a 0,因此该公式在语法上是正确的(+否则该编码为en )并将其传递给bc。ew

(但是,如果可以给出足够好的答案,我会使用更简单的第一种方法。)


谢谢,是的,如果满足该要求,它将起作用。但是,如果不是这样呢?
Tobias Kienzler 2012年

这是行不通的,因为这无法说明目录本身的大小(通常至少有2个链接,如果没有,则您将文件计数两次)。
斯特凡Chazelas

1
然后,有必要使用find打印所有文件的列表以及它们的索引节点和链接数;然后进行某种组合,sort | uniq -c以获取每个索引节点在树中出现的次数,然后过滤出那些链接数大于出现次数的索引...然后将该列表提供给du。但是如果满足要求,更好地节省精力。
安格斯2012年

@StephaneChazelas它确实可以工作,但是确实不考虑目录自身的大小。如果仅仅du有一个-d类似于参数ls的...
安格斯

还要注意的是在btrfs文件系统中,对目录的链接数量始终1,所以你需要添加一个! -type d
斯特凡Chazelas

5

基本上,您需要获取所有文件(非目录)的索引节点号和链接数,将链接数与每个索引节点的出现次数进行比较,如果它们不同,则排除文件。

假设它们都在同一个文件系统上,那么应该可以使用GNU find这样的东西:

find . -type d -printf '%k\n' -o -printf '%i %n %k\n' |
   awk '
     NF==1{t+=$0; next}
     {n1[$1]=$2; n2[$1]++; s[$1]=$3}
     END {
       for (i in n1)
         if (n1[i] == n2[i])
           t+=s[i]
       print t
     }'

是的,我所说的(感谢您的功劳)。但是,通过计数目录获得的额外准确性会因添加不精确的磁盘使用率而损失。
安格斯2012年

@angus,“ inexact磁盘使用率”是什么意思?
斯特凡Chazelas

没什么,我完全误解了%k报道。太好了,du根本不需要!到家后,我将更新我的答案。谢谢!
安格斯2012年

3

du 实际上是不会说谎的;)它解析提供给它的目录,仅计算指向它遇到的相同inode的所有硬链接中的第一个。

如果du仅询问在一个目录中看到的内容,则不必关心是否有指向相同内容的其他硬链接:

$ du -h daily.0 && du -hc daily.1
29G /daily.0
29G /daily.1

现在,将它放在同一行中(从的最新行开始,用于rsync增量备份--link-dest):

$ du -hc daily.0 daily.1
29G /daily.0
364M /daily.1
29G total

或整个备份目录:

$ du -hc --max-depth=1 /snapshots
29G /daily.0
364M /daily.1
537M /daily.2
333M /daily.3
30G total

“ daily.1”中任何引用已在“ daily.0”中引用的索引节点的文件(又称“真实”文件)将不计算在内。

因此,每天删除。1将在您的设备上节省364MB。

去掉

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.