このエントリーをはてなブックマークに追加
スポンサーリンク

dudu

duduコマンドとは

duduコマンドは、ディレクト毎の使用容量を調べるコマンドです。

Linuxについてくるduコマンドでは、指定ディレクトリ以下のディレクトリが全て表示されてしまいます。例えば、du -h /homeとした場合、/home直下のディレクトリ毎の合計だけが知りたいだけなのに、それ以下のファイルも全てリストしてしまいます。さらに、下の階層のファイルも全てフルパスで表示されるため、部分一致してしまうので、grepで範囲を絞るのも困難です。そこで、-sオプションをつけるわけですが、すると今度は指定ファイルの合計だけしか見ることができません。

そこで、指定したディレクトリだけの合計や、指定したディレクトリから指定階層分だけ下のディレクトリのみのサイズを表示させるコマンドを作成しました。

作成方法

まず、下記リンクをクリックして、ソース一式をダウンロードします。
dudu-1.04.tar.gzをダウンロード
これを、適当なコンパイル用のディレクトリにアップします。

tar xvzf dudu-1.04.tar.gz
cd dudu-1.04
./configure
make
sudo make install

これでコンパイルが通って、実行ファイルが/usr/local/binにコピーされるハズですが、うまくいかない場合は下記のconfigureオプションを試してみてください。

configureオプション

--prefix=インストールディレクトリ
デフォルトは/usr/local/binになっていますが、いきなりパスの通った所に置くのは危険と感じた、などの場合は、インストールする ディレクトリを指定してください。

--lib=ライブラリの場所
configureスクリプトは、libm.aライブラリを/usr/lib64、/usr/local/lib64、/usr/lib、 /usr/local/libの順に探します。64ビット版OSではlib64とlibに同名のライブラリが入ってる事が多いのですが、64ビット版をリンクしないとワーニングが出てしまう場合があるので、なるべくlib64を優先的に使います。32ビット版OSではもともとlib64は存在しないため、/usr/libか/usr/local/libからlibm.aを見つけてリンクします。

しかし、それとは別に、指定した場所にあるものを使いたいという場合は、--lib=の後に指定してください。 最優先で探してリンクします。

--include=インクルードファイルの場所
インクルードファイルは、/usr/include、/usr/local/includeから 探しますが、それとは別に、特に指定した場所にあるものを 使いたい場合は、指定してください。

--help
オプションの説明が表示されます。

このサイトで使っているサーバー(CentOS4.5)では正常にコンパイルする事ができましたが、全てのLinuxでコンパイルできるとは限りません。Linuxのディストリビューションによってはエラーが出てしまう事も考えられますが、その際は申し訳ありませんが、エラーの内容をチェックしてソースやMakefileの修正をお願いします。

使い方

ソースが正しくコンパイルされていれば実行ファイルduduというファイルが作られ、make installした時に、/usr/local/binにコピーされたと思います。このバイナリファイルを実行します。
書式
dudu ディレクトリ 階層の深さ [オプション] pg_csv [-オプション] DB名 -q "ステートメント" [--help]
ディレクトリ
容量を調べたいディレクトリを指定します。 存在しないディレクトリやファイルを指定するとエラーになります。 省略するとカレントになります。

階層の深さ
指定したディレクトリより何階層下の情報を出すかを指定します。 省略すると0(指定したディレクトリそのもの)が指定された事になります。
オプション
-h
ファイルサイズを人間の読みやすい単位で表示します。 単位は1KBは1024バイト、1MBは1024KB…という風に、1024単位で繰り上がります。また、小数点以下は切り上げされます。ただし、 単位で区切った値が1桁の場合(つまり、5K、9Mなど)は、 小数点1位まで表示し、2位以下を繰り上げします。というアルゴリズムなので、du -h の表示とは若干の誤差が生じます。

-s
ファイルサイズ順にソートします。何も指定しないとディレクトリ名のアルファベット順で表示しますが、どのディレクトリが容量を食ってるかを調べたい時には、このオプションを指定すると便利です。

--force
ファイル数が10万を超えても、強制的に実行します。このオプションをつけた場合、ハードリンクが無限ループになっていたり、サーバーのメモリーが足りなくなるぐらいファイル数が多い場合には、最悪サーバーがダウンしてしまう可能性もあるため、あくまで自己責任において指定してください。

--help
簡単な説明が表示されます。

出力結果

dudu -h /home 1で、/homeから1階層下のディレクトリ毎の合計容量を表示してみましょう。

@ファイルサイズ
Aディレクトリ(フルパス)
Bトータルサイズ

ファイルサイズには、そのディレクトリ自身のサイズ(4096バイト)と、それ以下に含まれる全てのファイルサイズを含みます。

トータルサイズは、 個々のファイル/ディレクトリの合計が表示されます。階層0を指定した場合のファイルサイズと、階層1を指定した時のトータルは異なります。これは、階層1では指定ディレクトリそのもののサイズ(4096バイト)を含まないためです。

使用例


dudu -h /home
/home以下にあるファイルサイズの合計を表示します。
dudu -h /home 1
/homeから1階層下のファイルやディレクトリと、それぞれのサイズの合計を表示します。
dudu -h -s /home 1
/homeから1階層下のファイルやディレクトリと、それぞれのサイズの合計を、容量の消費の少ない順に表示します。
dudu /home 3
/homeから3階層下にあるファイルやディレクトリと、それぞれのサイズの合計を、バイト単位で(-hを指定してないので)表示します。
dudu -h
カレント以下にあるファイルサイズの合計を表示します。
dudu -h --force
カレント以下にあるファイルサイズの合計を表示します。ファイル数が10万以上あっても強制的に続けます。サーバーのメモリオーバーに注意してください。

制限事項

・シンボリックリンクについて
シンボリックリンクを辿る事ができません。シンボリックリンクは、リンクファイルそのもののサイズを合計します。

・ハードリンクについて
ハードリンクはアプリ側からは通常のディレクトリと同じに見えるため、どうしても辿ってしまいます。そのため、ハードリンクの先にパーミッション違反があるとエラーになってしまいますし、ハードリンクでツリーが無限ループになっている場合はエラーで止まってしまいます。

・ファイル数の制限
指定ディレクトリ以下のファイルの情報を、シンボリックリンクやソケットも含めてメモリーに保存します。なので、あまりにファイルの多いディレクトリ(/とか)を指定すると、メモリーオーバーを起こして最悪サーバーがダウンしてしまうかもしれません。ハードリンクでツリーが無限ループになっている場合も同様です。

そこで、指定ディレクトリ以下のディレクトリが、再帰的に検査していく過程で10万を超えた時点でToo many directories or hard link infinite loop というエラーで強制終了するようにしています。

あくまで自己責任でお願いしますが、--forceオプションをつける事で、この制限をなくす事もできます。

エラーメッセージ

Too many directories or hard link infinite loop
指定ディレクトリ以下のディレクトリが10万を越えました。ハードリンクが無限ループになっている場合もこのエラーになります。

dudu: No such file or directory
指定されたファイルやディレクトリは存在しません。

dudu: Not a directory
指定されたパスはディレクトリではありません。

dudu: Permission denied
パーミッション違反です。指定ディレクトリの深い階層下に、リード権限のないのファイルやディレクトリがあるとこのエラーが出てしまいます。duコマンドのような、読める部分だけを表示したりはしません。

out of memory
メモリー不足です。ファイル名やファイルサイズを格納するためのメモリーをmallocで確保できませんでした。もう少し下の階層から指定するか、メモリーを増設するなどしてください。

FAQ

Q.du -h と dudu -hでサイズが全然違う。端数処理の誤差なんてレベルじゃない

A.du コマンドは基本的にファイルサイズをブロック(512Kバイト)単位で計算しますので、ファイルサイズが小さい場合に 512K単位で繰り上げられます。なので、その分サイズが実際より大きく表示されます。 一方、dudu コマンドでは、それぞれのファイルをバイト単位で足し算をしていますので、duコマンドよりもより正確なサイズで表示しています。

du コマンドで-bを指定した時の出力結果と、duduコマンドで-hを指定しなかった時の出力結果は、どちらもバイト単位での表示になるため、同一サイズが表示されると思います。

Q.df -h と dudu -h / でサイズが全然違う。端数処理の誤差なんてレベルじゃない

A.df -h コマンドはあくまで物理的にディスクを消費している量の合計ですが、dudu で計算しているのはソケットや/devやシンボリックリンクなど個々のファイルの理論上のサイズの量の合計です。なので、どうしてもdf -hの方が少なく表示されます。

ディスクの残りを調べたい時はdf、ディレクトリごとに消費容量の割合を見たい場合はdudu、という風に使い分けるようにしてください。

更新履歴

■2011-08-31 バージョン1.04
make installを追加しました。

■2009-01-09 バージョン1.03
サイズ順でソートするオプション -s を追加しました。
ファイルが10万を超えても強制的に続けるオプション --forceを追加しました。

■2009-01-07 バージョン1.02
2Gを超えたファイルがマイナスとしてカウントされてしまいましたので、コンパイル時に-D_FILE_OFFSET_BITS=64を指定するようにしました。configureスクリプトが変更になっています。

■2008-12-04 バージョン1.01
検索できるディレクトリの数を1万から10万に増やしました。
.と..の分のメモリーを確保しないようにしました。
0階層目のディレクトリの情報を保存する分のメモリーを確保してなくて、.や..の分を余分に確保してるために助かっていたのを修正しました。
指定階層ではないファイルの名前はメモリーに残さず、サイズ取得後にfreeで開放するようにしました。

■過去のバージョン
dudu-1.03.tar.gz
dudu-1.02.tar.gz
dudu-1.01.tar.gz
dudu-1.00.tar.gz

免責事項

このプログラムでは、dirent.h内で定義しているscandir関数と、lstat関数を使ってファイルの情報を再帰的に読み込んでいるだけの単純なものです。ファイルに対して書き込みは一切していないので、最悪でもファイルが破損したりする事はないと思いますが、ご利用に関してはあくまで自己責任でお願いします。

当プログラムによって生じた一切の責任は負いかねますのでご了承ください。
スポンサーリンク