複数のディレクトリ/フォルダ引数を指定する場合(du -s
そのうちのいくつかは他の引数の親引数)、引数の順序はその引数が出力du
に表示されるかどうかによって異なります。また、親ディレクトリの表示サイズも変更されます。
たとえば、次の3つのディレクトリの概要を見たいとします。
/ (actual size: 174G)
/etc
/home
コマンド#1
✔️以下の最初のコマンドが正しく提供されたので、3行の出力が表示されると予想しました。
❌ ただし、/のサイズは表示されたサブディレクトリのサイズを引いたサイズなので、間違っています。/
du -sh /home /etc /
79G /home
30M /etc
95G /
コマンド#2
ただし、引数の順序が異なり、親ディレクトリが子ディレクトリの前に指定されている場合、子ディレクトリはまったく表示されません。
❌3つのディレクトリパラメータがあり、2つだけが表示されます。
❌ また、forのサイズはfrom/
のサイズを減算するため、間違っています。/home
/
du -sh /home / /etc
79G /home
95G /
コマンド#3
❌3つのディレクトリパラメータのうち1つのみが表示されます。
✔️ /
正しい合計サイズを表示します。
du -sh / /home /etc
174G /
質問
これはなぜ重要ですか?再度カウントするのではなく、内部的に計算する方法と関係がないかと思いましたが、驚くべきことに、これらのコマンドはまったく異なる結果をもたらしました。
与えられた引数の順序に関係なく、
du
常に予想される3行の出力と上位ディレクトリの正しい合計サイズ(たとえば、上記の174G)を提供する方法はありますか?/
つまり、期待される出力は次のようになります。79G /home 30M /etc 174G /
私はこれが効率的になりたいです。つまり、最上位ディレクトリを一度だけ再帰的に巡回し、表示されているすべてのサブディレクトリについて事前に計算された情報を再利用する必要があります。代わりにfind
+を使用してxargs
複数の別々のコマンドを実行すると、du
各レベルの子孫に対して引き続き多くの再スキャンが実行されます。
答え1
du
ディスク使用量を報告します。
ファイルが2つの異なる名前(ハードリンクを介して含む)で見つかった場合でも、ファイルごとに一度だけディスク使用量を計算します。
これは、同じファイルへのハードリンクa
の場合にのみ報告され、2番目のファイルを処理するときにのみ報告され、これが考慮されたことを認識します。b
du a b
a
du b a
b
du
同様にdu / /etc
、降順ソート時に見つかったすべてのファイルは/etc
すでに処理中に考慮されるため、/
報告する内容はありません/etc
。
あなたの場合、報告された総ディスク使用量は常に同じで一貫性があります。つまり、174Gです。これは、その中のすべてのファイルが使用するディスク容量であるためです。
GNU実装では、du
/オプションを使用して重複排除を無効にできます。ただし、これらのディレクトリの累積ディスク使用量はもはや正確ではありません(ハードリンクがある単一ディレクトリの場合でも)。-l
--count-links
/
累積ディスク使用量を互いに/home
独立して取得するには、次の3回の呼び出しを実行してください。/etc
du
du -s /
du -s /home
du -s /etc
またはzsh
:
for d (/ /home /etc) du -s $d
/home
それにもかかわらず、外部にハードリンクがあるファイルがある場合、そのファイル/home
とそのコンテンツの両方を削除しても、報告された分のスペースは必ずしも確保されませんdu
。
答え2
このdu
コマンドは、ファイルやディレクトリを複数回数えるのを避けるために非常に長くなります。これはから来たものですPOSIXの定義どの状態、
ファイルオペランドの下で複数回発生し、リンク数が1より大きいファイルは、1つの項目に対してのみ計算および記録する必要があります。リンク数が 1 以下のファイルが 1 回だけ計算され、記録されるか、発生するたびに記録されるかは、実装によって定義されます。あるファイルオペランドの下に現れるファイルが別のファイルオペランドとして計算されるかどうかは、実装によって定義されます。
GNUの場合は、du
コマンドを使用して使用済みdu -sh /home /
スペースを確認し、/home
使用済みスペースを確認します。/
すでに訪れた場所を除くdu
。
du
3つのディレクトリ階層の例に対して完全に独立した値が必要な場合は、3回呼び出す必要があります。
du -sh /
du -sh /home
du -sh /etc