他の場所でハードリンクされていないファイルによって使用されているスペースのみを「du」にする方法は?


14

rsync --link-destスペース節約スナップショットを使用して、実際にどのくらいのスペースを節約したかを知るにはどうすればよいですか?またはより一般的な:

ディレクトリ構造以外の場所ハードリンクされていないファイルのみを考慮して、ディレクトリがどのくらいのスペースを使用しているかを調べる方法は?別の質問:そのディレクトリを削除すると、実際にどれだけのスペースが解放されますか?(du -hsうそになるでしょう。ハードリンク自体に必要なスペースが含まれる場合があります)


2
デフォルトでは、GNU duは、-l/ --count-linksオプションを使用しない限り、ファイルサイズがハードリンクされている場合でもファイルサイズを1回だけカウントします。このduオプションを使用して、または使用せずにツリー全体で2回実行します。サイズの違いは、すべてのディレクトリで保存したスペースの量です。
jw013

回答:


9

内部ハードリンクがない(つまり、複数のハードリンクを持つすべてのファイルがツリーの外部からリンクされている)と仮定すると、次のことができます。

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呼び出しは、ディレクトリに対してそれを行います。

2番目findは、リンクカウント、iノード、およびディスク使用量を出力します。このリストを渡してsort | uniq -c、リスト(ツリー内の表示数、リンク数、iノード、ディスク使用量)を取得します。

私たちは、合格することをリストawk、最初のフィールド(外観の数)が2番目(ハードリンクの数)以上である場合、つまりツリーの外側からこのファイルへのリンクがないことを意味し、4番目のフィールド(ディスク使用量)プラス記号とバックスラッシュが添付されています。

最後にaを出力する0ので、式は構文的に正しく(+そうでなければenになります)、それをに渡しbcます。ふう。

(ただし、十分な答えが得られる場合は、より単純な最初の方法を使用します。)


おかげで、はい、その要件が満たされていれば機能します。しかし、そうでない場合はどうでしょうか?
トバイアスキンツラー

ディレクトリ自体のサイズを考慮することができないため、これは機能しません(通常、少なくとも2つのリンクがあり、リンクがなかった場合、ファイルが2回カウントされます)。
ステファンシャゼル

1
次にfind、すべてのファイルとそのiノードおよびリンクカウントのリストを印刷するために使用する必要があります。次に、いくつかの組み合わせを使用sort | uniq -cして、各iノードがツリーに表示される回数を取得し、リンクカウントが出現回数よりも大きいものを除外してから、そのリストをにフィードしますdu。ただし、要件が満たされている場合は、労力を節約してください。
アンガス

@StephaneChazelas動作しますが、ディレクトリ自体のサイズを考慮していないのは事実です。's ...に似du-dパラメータのみがあった場合ls
アンガス

上のことにも注意してくださいbtrfsファイルシステム、ディレクトリのリンク数は常に1あなたが追加する必要があると思いますので、! -type d
ステファンChazelas

5

基本的に、すべてのファイル(ディレクトリ以外)のiノード番号とリンク数を取得し、そのリンク数を各iノードの発生数と比較し、それらが異なる場合はファイルを除外する必要があります。

すべてが同じファイルシステム上にあると仮定すると、次のようなものが機能するはずです(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
     }'

ええ、私が言ったこと(クレジットをありがとう)。ただし、ディレクトリをカウントすることで得られる余分な精度は、不正確なディスク使用量を追加することで失われます。
アンガス

@angus、「不正確なディスク使用量」とはどういう意味ですか?
ステファンシャゼル

何もない、私は%k報告されたものについて完全に間違っていた。それduは素晴らしい、まったく必要ありません!家に帰ったら答えを更新します。ありがとう!
アンガス

3

du 実際に嘘をつくことはありません;)検出されたdir(s)を解析し、遭遇した同じiノードを指すすべてのハードリンクの最初のもののみをカウントします。

du1つのディレクトリでのみ何を見るかを尋ねると、同じコンテンツを指す他のハードリンクがあるかどうかは気にしません。

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

ここで、同じ行にdirsを指定します(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.0」ですでに参照されているiノード(別名「実際の」ファイル)を参照する「daily.1」のファイルはカウントされません。

したがって、daily.1を削除すると、デバイスに364MB節約されます。

削除する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.