file-expire - 特定のディレクトリ内の古いファイルを削除するスクリプト
最近ディスク容量がきつきつになってきているので、古いファイルを消したり動画をDVDに島流ししたりでなんとか空容量を工面している状況だ。
店員さんに「ハードディスクはしょせん消耗品、3年持たないものだ」と言われた80GBのハードディスクも稼動して3年半になる…逝きそうな気配はまったくないが、寿命は近いだろう。せっかく長生きしてくれているんだから最後の瞬間まで使ってあげようと思う。待てば待つほどハードディスクは安くなるんだから。
知らない間にプログラムのログファイルやキャッシュファイルが溜っていって、ディスクを埋め尽くすことはないだろうか?古いファイルはたまに掃除してあげると空容量が確保できる。だが、ディスクの掃除を手作業でやるとかなり面倒なので自動化してしまうのが一番。そこでこのスクリプトを。activesupportを使っているのでgem install activesupportしよう。railsの人は不要。
#!/usr/bin/env ruby require 'rubygems' require 'active_support/core_ext/numeric' require 'fileutils' $files_to_expire = [] ################ API def file(secs_before, *globs) _globs(globs) do |file| stat = File.stat(file) next if stat.directory? $files_to_expire << [file, stat.mtime, :F] if stat.mtime < secs_before.ago end end def directory(secs_before, *globs) _globs(globs) do |file| stat = File.stat(file) $files_to_expire << [file, stat.mtime, :D] if stat.directory? and stat.mtime < secs_before.ago end end ################ /API def _globs(globs) globs.each do |glob| Dir[File.expand_path(glob)].each do |file| begin yield(file) rescue end end end end def show_expires(expire_files=$files_to_expire) expire_files.each do |file, mtime, f_or_d| puts "#{f_or_d} #{mtime} #{file}" end end def delete_expires(expire_files=$files_to_expire) expire_files.each do |file, mtime, f_or_d| puts "#{f_or_d} #{mtime} #{file} (remove)" begin if f_or_d == :F FileUtils.rm_f file else FileUtils.rm_rf file end rescue $stderr.puts "Failed to unlink #{file}." end end end require 'optparse' @func = :show_expires @config = File.expand_path "~/.file-expire.rb" ARGV.options {|o| o.on("-d", "Delete old files.") {|x| @func = :delete_expires } o.on("-c CONFIG", "--config=CONFIG", "Set config file instead of default one.") { |x| @config = x } o.parse! } begin load @config rescue LoadError $stderr.puts "#@config does not exist or has error.", $! end __send__ @func
このスクリプトは設定ファイル ~/.file-expire.rb に書かれた指示に基いて古いファイルやディレクトリを消していく。~/.file-expire.rbはれっきとしたRubyスクリプトで2種類の指示を出せる。
file 期限, 消すファイルのパターン... directory 期限, 消すディレクトリのパターン...
消すファイルのパターンはDir[]で指定できるワイルドカードで複数指定できる。どちらも期限よりも古いファイルやディレクトリを消す。fileはファイルのみ削除し、directoryはディレクトリ内のファイルをもまるごと消す。
たとえば以下の指示は、1年以上前の /log/palm-backup/db 内のディレクトリすべてと、1週間以上前の w3m の一時ファイルを削除する設定だ。数字の後ろにはrailsでおなじみの時間単位のメソッドをつけられる。(activesupportの機能)
directory 1.year, "/log/palm-backup/db/*" file 1.week, "~/.w3m/w3mtmp*", "~/.w3m/w3mcache*", "~/.w3m/w3msrc*"
誤動作を防ぐため、引数なしで起動した場合はファイルを消さずに表示するのみである。消すには-dオプションをつけること。
設定ファイルに書いているのは、たんなる宣言に過ぎない。宣言を読み込むと該当するファイルたちが配列に溜まっていく。Rubyは気楽にDSLが作れていいものだ。