結論
duコマンドをrubyでラッピングしたスクリプトを作りました。
expand.rb
という名前を作って、下のスクリプトを貼って、以下のように実行します。
# ruby expand.rb (調べたいパス)
$ ruby expand_du.rb /var/lib/
7GB /var/lib/
3GB /var/lib/jenkins
2GB /var/lib/docker
1GB /var/lib/mysql
...
4KB /var/lib/mysql-files
du_-k_--max-depth_1_var_lib__20200516231438.logに保存しました
スクリプト(github)
# 使い方
# ruby expand_du.rb パス
# 例:ruby expand_du.rb ~
#
# 効果
# - パスに対してduコマンドを実行
# - 実行結果を標準出力とファイルに吐き出す
#
# 引数
# - パス: duコマンドを行う対象パス
require 'rbconfig'
def main(target_path)
return puts "ArgumentError: パスを引数に入れてください" if target_path.nil?
max_depth_option_str = if os == :macosx
"-d"
else
"--max-depth"
end
exec_command = "du -k #{max_depth_option_str} 1 #{target_path}"
du_result_str = `#{exec_command}`
return if du_result_str.empty?
output_disksizes(du_result_str, exec_command)
end
def output_disksizes(du_result_str, exec_command)
disk_usages = du_result_str
.split("\n")
.map{|du_result| DiskUsage.new(du_result)}
.sort{|x, y| x.size <=> y.size}.reverse
output_filename = "#{exec_command.gsub(/( |\/){1,}/, "_")}_#{Time.new.strftime("%Y%m%d%H%M%S")}.log"
output_file = File.open(output_filename, "w")
disk_usages.each do |disk_usage|
puts disk_usage.to_s
output_file.puts(disk_usage.to_s)
end
output_file.close
puts "#{output_filename}に保存しました"
end
class DiskUsage
attr_reader :size, :path
def initialize(du_result_line)
du_result_params = du_result_line.split(" ").map(&:strip)
@size = du_result_params[0].to_i
@humanreadable_size, @humanreadable_unit = calc_humanreadable_size
@path = du_result_params[1]
end
def to_s
# NOTE とりあえず5桁を指定。必要になったら増やす
"#{sprintf("%5d" % @humanreadable_size)}#{@humanreadable_unit} #{@path}"
end
def humanreadable_size_with_unit
"#{@humanreadable_size}#{@humanreadable_unit}"
end
private
def calc_humanreadable_size
return [@size, "KB"] if mb_size < 1
return [mb_size, "MB"] if gb_size < 1
return [gb_size, "GB"] if tb_size < 1
[tb_size, "TB"]
end
def kb_size
@size
end
def mb_size
kb_size.fdiv(1024).round(1)
end
def gb_size
mb_size.fdiv(1024).round(1)
end
def tb_size
gb_size.fdiv(1024).round(1)
end
end
def os
case RbConfig::CONFIG['host_os']
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
:windows
when /darwin|mac os/
:macosx
when /linux/
:linux
when /solaris|bsd/
:unix
else
:unknown
end
end
経緯
レンタルサーバやMacの容量がいっぱいになったときに、どのフォルダが原因なのか知りたくなります。
そこでMacならストレージ使用状況を見たり、レンタルサーバでもdfコマンドとかで全体のどれくらいを使っているかはわかります。しかし全体がわかるだけでどのフォルダが原因かわかりません。
そこでターミナルを使える人が使えるのはduコマンドです(lsコマンドも候補にあがるんですが、lsコマンドは直下のファイルの大きさはわかるんですが、フォルダがどれだけ大きいかはわかりません)。
しかしこのduコマンドなんですが、UNIXコマンドであるせいか、ちょっといまいちなんですよね。
ソートがいまいち
読みやすくするのに -h オプションをつけて、sortコマンドを使ってサイズを降順で出すんですが、そうすると5KBが4GBよりも上に来るんですよね。数字だけ見ているので仕方ないんですが。
記録するのに2回打つのが面倒くさい
duを使うと標準出力に結果を出してくれるけれど、出したあと結局結果を記録したくなります。最初からファイル出力すればいいんですが、ファイル出力してからcatするのが面倒なんですよね。工夫してコマンド打てばファイルにも標準出力にも出してくれるんですが、duコマンド必要なときって大抵急いでいるので、楽にやりたかったんです。
スクリプトの特徴
↑の問題を解決したスクリプトが最初に載せたスクリプトです。
特徴は次のようになります。
- 単位を考えた上でソートしてくれる
- 標準出力にもファイルにも出してくれる(&どのフォルダを調べたかわかるファイル名で出力してくれる)
完全に自分用に作ったんですが、同じことに困っている方がいらっしゃったら使ってみてください。
Comments
Let's comment your feelings that are more than good