ファイルのバックアップをとりながら編集する
NetBSDというかpkgsrcのpkgviを参考に、ファイルのバックアップをとりながらそのファイルを編集するエディタコマンドのラッパーを書いてみました。編集後にファイルが更新されていたら、「ファイル名.bkYYYYMMDD」というファイルで元のファイルを保存します。もし「ファイル名.bkYYYYMMDD」が存在していたらバックアップはとりません(なので一日に2回編集した場合、1回目の編集後のファイルはバックアップされません)。
ファイル: bkvi.rb
#!/usr/bin/env ruby class Editor def initialize @editor = ENV['EDITOR'] @editor ||= 'vi' end def edit(filename) run(@editor, filename) end private def run(*args) Process.waitpid(fork { exec(*args) }) end end if __FILE__ == $0 require 'optparse' require 'tempfile' require 'fileutils' include FileUtils Version = '0.1a' OptionParser.new do |opt| opt.banner = "Usage: #{$0} filename" opt.parse!(ARGV) if ARGV.size < 1 puts opt.help exit 1 end end filename = ARGV.shift unless FileTest.file?(filename) $stderr.puts "#{$0}: no such file #{filename}." exit 1 end editor = Editor.new ext = Time.now.strftime('.bk%Y%m%d') if FileTest.file?(filename + ext) editor.edit(filename) puts "#{$0}: backup file already exists." exit 0 end tempfile = Tempfile.new(filename) open(filename, 'r') do |file| copy_stream(file, tempfile) end tempfile.close editor.edit(tempfile.path) if cmp(filename, tempfile.path) puts "#{$0}: file unchanged." else mv(filename, filename + ext) mv(tempfile.path, filename) puts "#{$0}: file was modified." end rm(tempfile.path + '~', { :force => true }) rm(tempfile.path + '.bak', { :force => true }) end