それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Rubyでディレクトリ・ミラーツール rbsync

よくやるファイルミラー処理をまとめたrubyクラスを作った

rsync がアレコレ覚えること多くて気に入らない。Rubyでミラーツール作ってんだ。
サイトの更新作業や、デジカメのバックアップ、PC環境など、よくつかうパターンがある。コレに合わせrsync を考えたり漏れのないロジック考えるのが。毎回考えるのが面倒になってきた.

さくっと出来るように。Rubyでクラス書きました.

こんな悩みにオススメ

ファイル同期のこんな悩みにオススメです.

  1. 上書きされた.ファイル消えた・・・
  2. 送信先でファイル名が変わってて、ゴミファイルが増えた
  3. 送信先のファイルを別名にしてから、転送する
  4. 同じファイルが別名でいくつもある
  5. 更新日付の新しいモノだけを転送したい。
  6. ファイルの中身をみて同期してほしい。

rbsyncで解決

  • ファイル名が変わっていても、同期する。
  • ファイル名が衝突したら,別名で転送する。

これだけ。こういうツール無いんですよね。Windowsアプリは簡単に自動化できないのです

インストール

gem instal rbsync

2011-06-14の最新版は 0.0.7

rubyから使います.

require 'rbsync'
rbsync = RbSync.new
rbsync.sync("src","dest")

ファイル名が違っても同期して!

ファイルをバックアップしたけれど,ファイル名を書換えてしまって,ウマく同期できないときがあります。また、多人数でサーバー弄ってると、誰かがいきなりファイル名を変えていたりして困ります.

ファイルのハッシュ値をベースに同期してみたらどうか

ファイル名が変わっていても、中身が同じなら,同期対象から除外できるはず.
やってみた

require 'rbsync'
rbsync = RbSync.new
rbsync.sync("src","dest",{:check_hash=>true})
src test.txt "47bce5c74f589f4867dbd57e9ca9f808"
dst test.bak "47bce5c74f589f4867dbd57e9ca9f808"

ハッシュが同じなら転送しない.


上書きする前にバックアップとって!

同期するときに、上書きするなら,元ファイルの名前を別名にしてから転送しみたら安全な気がして作ってみた.

元ファイルを別名に保存してから転送してみたらどうか

やってみた

src test.txt 2011-06-14
dest test.txt 2011-06-12

src test.txt 2011-06-14
dest test.txt 2011-06-14 # 同期したファイル
dest test_20110614022255.txt 2011-06-12 # 保存ファイル

ruby のコード

require 'rbsync'
rsync =RbSync.new
rsync.sync( "src", "dest",{:backup=>true,:update=>true} )

同期するときに、別名で同期する

Windowsのファイルコピーみたいに,同じファイル名があれば、別名にして転送すれば良いんじゃないか。
そう思って作ってみた

windows的にtest(1).txt にして欲しい.

実装した

同期前
src test.txt 2011-06-14
dest test.txt 2011-06-12
同期後の状態
src test.txt 2011-06-14
dest test(1).txt 2011-06-14 # 別名をつけて転送
dest test.txt 2011-06-12

使い方

require 'rbsync'
rsync =RbSync.new
rsync.sync( "src", "dest",{:rename=>true} )

まだ作ってない

  • SCP/FTP/SSH 経由での転送.
    • 今のところネットワーク越しの転送は smbclient/ sshfs を替わりに使う
  • 進捗表示.

便利なので使ってみては

便利になると思うので使って見て下さい。

思ったことなど

ディレクトリをミラーするときに,いつもファイル名や,上書きを気にしながらやる。面倒だ。
いつも同じ事やってると想ったのでクラスを作りました。

プロトタイプなので誤作動もあるかもしれないです.報告もらえれば全力で対応します.

休日を突っ込んで作ったが,ファイルは手作業でコピーしたので,活躍の機会があまりない.あたた

作った経緯 rsyncの大失敗

rsync を使い込んでるがそれでも失敗する.

HTC Desireのカメラアプリが削除したファイル名を再利用するので,同期後に,デジカメファイルが大量に消えた。イラッとして作った.
ScanSnapのフォルダをRsyncしてたんだけど、名前を変えまくって,同期出来なくなったのでイラッとなって作った.

追記 2011-06-14 17:38

・サブディレクトリの処理がエラーになったのを修正
・テストにタイムスタンプチェックを追加
・ctimeの処理がWindows/Linux/Cygwinで微妙に違うのではまりそう.

追記 2011-06-14 3:38

プログレスバーも作った.こんな感じで出るようになった.

プログレスバー使う

rsync = RbSync.new
rsync.conf[:progress] = true # 進捗表示
rsync.sync("/home/takuya/desktop/src","/home/takuya/desktop/dest" )

表示サンプル

$ ruby sample_sync.rb

start 4/9
copying ./src/逆引きRubyまとめノート(1).pdf to ./dest/逆引きRubyまとめノート(1).pdf
############################## 100% done
start 7/9
copying ./src/遊びマップ-10.11.pdf to ./dest/遊びマップ-10.11.pdf
############################## 100% done
start 8/9
copying ./src/阪急TOKK-10-01版.pdf to ./dest/阪急TOKK-10-01版.pdf
############################## 100% done
start 9/9
copying ./src/阪急TOKK-10-15版.pdf to ./dest/阪急TOKK-10-15版.pdf
############################## 100% done

追記 2011-06-15 0:25

WindowsのRubyはファイルの更新日時がミリ秒単位では取れません.
実装依存らしいので、Windowsの場合はWin32を使うように書換えないとダメみたい.


追記 2011-07-10

エラー修正。スレッド動作の修正。スレッドがFile.size(entry)でErrorになってたのを修正。 スレッドがファイル作成前にsizeを実行してNotFoundエラーで落ちてた。

cygwin の日本語UTF8/SJIS環境で File#dirname がひらがなパスだとウマく取り出せなかったので適当に修正

追記 2011-07-28

ファイルチェックが冗長で、ファイルサイズを何回も取りに行ってるところを一カ所だけ省略した。