linux上のサイズの大きいディレクトリを表示させるrubyスクリプト

大容量のHDDが安価に手に入る時代において何故かうちのサーバー環境はいっぱいいっぱい。
つい昨日もdfコマンドを実行してみたら空きが全く無くなっていました。。
こんな時はデータを削除していくことになるんですが、全部を見ていくのはできないのでどのディレクトリにでかいデータがあるかな、とあたりをつけるのにduコマンドを使います。そのまま実行すると再帰的に下層のディレクトリサイズまで表示してしまうので、-hsオプションをつけます。例えば/usr /homeの2つの容量を確認するには次のようにします。

du -hs /usr /home

けど引数の対象ディレクトリをいちいち手で入力するのが面倒なので、楽したい。というわけでrubyじゃ!
こんな感じで使いたい。

./dirsize.rb /

実行結果はこんな感じで。

95M     /lib
6.0M    /bin
903M    /proc
113M    /var
7.6M    /boot
459M    /home
・・・


つまり引数に対象となるディレクトリを渡せばその直下にある全ディレクトリの情報を表示してくれるというもの。ただ、せっかくなのでちょっとこだわってみた。

  • 見つけたいのは大きいサイズのものだけなので、単位がMのものとGのもののみを表示したい
  • コマンド引数を省略した場合はカレントディレクトリ以下を表示して欲しい
  • 「.」とか「..」ってのがディレクトリ候補としてあがってくるけど、そいつらは対象にしたくない
  • コマンド引数に「/home/」を渡した場合でも「/home」を渡した場合でも表示する際は「/home/hoge」のように表示して欲しい。「/home//hoge」は美しくないから。

これらを実現するrubyプログラムは以下のようになりました。

#!/usr/bin/ruby

base = ARGV[0] || `pwd`.chop!

Dir::foreach(base) do |d|
  next if d =~ /\.{1,2}/ || !(FileTest::directory? "#{base}/#{d}")

  line = `du -hs #{base.sub(/\/$/, "")}/#{d}`
  puts line if line =~ /^\d+(\.)?\d+(G|M)/
end

正規表現を多用すると暗号のようになってしまいますね。。