如何仅“du”其他地方未硬链接的文件所用的空间?

如何仅“du”其他地方未硬链接的文件所用的空间?

用于rsync --link-dest节省空间的快照,我怎样才能知道我实际节省了多少空间?或者更一般地说:

如何仅考虑其他地方未硬链接的文件来计算目录使用了多少空间外部目录结构?以不同的方式询问:删除该目录后实际上会释放多少空间? (du -hs可能会撒谎。可能包括硬链接本身所需的空间)

答案1

假设没有内部硬链接(即每个具有超过 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打印链接计数、inode 和磁盘使用情况。我们传递该列表以sort | uniq -c获取列表(树中出现的次数、链接计数、索引节点、磁盘使用情况)。

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

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

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

答案2

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

假设它们都在同一个文件系统上,类似这样的东西应该可以工作(使用 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
     }'

答案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”中引用的 inode(又名“真实”文件)的任何文件将不被计算在内。

因此,删除 daily.1 将在您的设备上节省 364MB 的空间。

消除

相关内容