サーバーの設定をバックアップするスクリプト
Linux等のサーバー設定ファイルだけ抜き出したい時に、
Findで探せばいいんだけど、ルートに対して行うことは、負荷が高くなる上に
使い勝手がよくない。
ということで以下のような感じで使えるスクリプトを書いてみました。
保存する時は、backupfilesで保存してもらえればOKです。
7 backupfiles -o /home/seasons -i /etc/ -v -m "\.conf|\.sh|\.rb|\/\.[A-Za-z]+$"
以下スクリプト本体。
1 #!/usr/bin/ruby -Ku 2 require 'find' 3 require 'pathname' 4 require 'fileutils' 5 require 'optparse' 6 require 'pp' 7 8 $KCODE = "u" 9 10 # ========================================================================= 11 # Extension Pathname util 12 class String 13 14 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 15 # to_path method 16 # 17 # exp) 18 # path = '/usr/local/test.txt' 19 # path = path.to_path 20 # 21 # p path.to_s #=> '/usr/local/test.txt' 22 # p path.file? #=> true 23 # 24 def to_path 25 26 Pathname.new( self ) 27 28 end 29 30 end 31 32 # ========================================================================= 33 # Extension Pathname tools 34 class Pathname 35 36 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 37 # Show Path -> As String 38 # 39 def name 40 41 self.to_s 42 43 end 44 45 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 46 # Join Path + FilePath 47 # 48 # args) 49 # file ... filepath 50 # 51 # exp) 52 # 53 # path = '/usr/local/devel' 54 # path = path.to_path! 55 # path.joinpath( './test.txt' ).name #=> /usr/local/devel/test.txt 56 # 57 def joinpath( file ) 58 59 filepath = file.to_path 60 return nil unless filepath.exist? 61 newpath = (self + filepath).cleanpath 62 63 end 64 65 end 66 67 # ========================================================================= 68 # Find Extension 69 class FindPowerToys 70 71 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 72 # initialize 73 # 74 # args) 75 # searchpath ... searchpath 76 # 77 def initialize( searchpath ) 78 79 @searchpath = searchpath.to_path 80 @filelist = [] 81 raise ArgumentError , "### searchpath is not found!! => #{searchpath}" unless @searchpath.exist? 82 Find.find( @searchpath.name ){ |fname| @filelist << fname } 83 @filelist = @filelist.select{ |item| @searchpath.joinpath( item ) if @searchpath.joinpath( item ) } 84 @filelist.map!{ |item| @searchpath.joinpath( item ).name } 85 86 end 87 88 89 # ----------------------------------------------------------------- 90 # Entry file items(iterator) 91 # 92 # exp) 93 # fp = FindPowerToys.new('/') 94 # fp.files do |fname| 95 # p fname #=> Show Root=/ FileEntries 96 # end 97 # 98 def files 99 100 @filelist.each do |item| 101 yield item 102 end 103 104 end 105 106 end 107 108 # ========================================================================== 109 # File Copy Extension 110 # 111 # args) 112 # dstpath ... destination file path 113 # srcpath ... source file path 114 # verbose ... verbose show output 115 # 116 # exp) 117 # FileCopyUtils.copyr( '/home/seasons/' , '/usr/local/hoge.txt' ) 118 # 119 # /usr/local/hoge.txt -> /home/seasons/usr/local/hoge.txt 120 # 121 class FileCopyUtils 122 123 def FileCopyUtils.copyr( dstpath , srcpath , verbose=false ) 124 125 # Check valid path 126 srcpath = srcpath.to_path 127 return unless srcpath.file? 128 129 dstpath = dstpath.to_path 130 raise ArgumentError , "### Filepath is not found!! => #{srcpath}" unless srcpath.exist? 131 raise ArgumentError , "### Filepath is not found!! => #{dstpath}" unless dstpath.exist? 132 133 # Create Recursive Directory 134 dstpath += '.' + srcpath.name 135 dstpath = dstpath.cleanpath 136 dir = File.dirname( dstpath.name ) 137 FileUtils.mkdir_p( dir ) unless FileTest.exist? dir 138 139 # Copy Files 140 FileUtils.cp( srcpath.name , dstpath.name ) 141 print "#{srcpath.name} -> #{dstpath.name}\n" if verbose 142 143 end 144 145 end 146 147 # ========================================================================== 148 # Main 149 # ========================================================================== 150 def main 151 152 #=> Parser 153 outputPath = nil 154 inputPath = nil 155 patternMatch = nil 156 verbose = false 157 parser = OptionParser.new 158 parser.banner = "\nUsage: #{$0} -o OUTPUTPATH -i INPUTPATH -m MATCHPATTERN\n[mailto]: keisuke@hata.biz" 159 parser.on( '-o' , '--output=OUTPUTPATH' ){ |output| outputPath = output } 160 parser.on( '-i' , '--input=INPUTPATH' ){ |input| inputPath = input } 161 parser.on( '-m' , '--match=MATCHPATTERN'){ |pattern| patternMatch = pattern } 162 parser.on( '-v' ){ |verboseflg| verbose = verboseflg } 163 164 def parser.error(msg = nil) 165 $stderr.puts msg if msg 166 $stderr.puts help() 167 exit 1 168 end 169 begin 170 parser.parse! 171 rescue OptionParser::ParseError => err 172 parser.error err.message 173 end 174 parser.error '### no output path' unless outputPath 175 parser.error '### output is not path' unless outputPath.to_path.directory? 176 parser.error '### no intput path' unless inputPath 177 parser.error '### intput is not path' unless inputPath.to_path.directory? 178 parser.error '### ARGV is Empty' unless ARGV.empty? 179 180 #=> FileBackup 181 match = nil 182 match = Regexp.new(/#{patternMatch}/) 183 fp = FindPowerToys.new( inputPath ) 184 fp.files do |fname| 185 if !match or (match and fname =~ match) 186 FileCopyUtils.copyr( outputPath , fname , verbose ) 187 end 188 end 189 end 190 191 main() if __FILE__ == $0