RT:ドヤリング

Twitterのドヤリングアカウント(@doyaling)の出張所です。文章が長くなるときにコチラ使用します。

rsyncコマンドで外付けHDD同士を同期し、バックアップする

rsyncAutomatorでフォルダ同期を行う

 外付けHDDにいろいろデータを入れてるんですが、それをまるごと別の外付けHDDにバックアップする方法を考えておりました。外付けHDDを3台持っていて、1台目はオリジナルデータ用、2台目はiMac本体のTimemachineバックアップ用、そして3台目が空いてるので、これを1台目のバックアップ用にしようかなと。


 f:id:doyaling:20150216102351j:plain:w300


 最初、RAIDで外付けHDD同士をミラーリングを設定しようとも思いましたが、やったことなくてよく分からないし、頻繁に抜いたり挿したりする外付けHDDでRAIDって大丈夫なのか?っていう恐怖もあったので、とりあえずやめとくことに。
 Timemachineのバックアップ対象にするという手もありますが、持っているHDDの容量の関係でちょっとむずかしい(ややこしいので具体的な事情は省略)。


 結局なにがしたいかというと、1台目の外付けHDDを3台目の外付けHDDに「同期」したいということです。新しく追加したファイルをコピーし、削除したファイルは両方のHDDから消えるように。もちろん、まるごと差し替えではなく、変更があったファイルだけを更新してくれればよい。


 フォルダの同期をしてくれるアプリは、ここにいくつか紹介されています。
 http://veadardiary.blog29.fc2.com/blog-category-56.html


 一応、イメージに最も近いのは「Simple Sync」っていうアプリで、使ってみたら動いたんですが、2008年のアプリでその後アップデートされていないせいか、ちょっと変なところがある。
 そこで、もうめんどうなので、「rsync」というシェル(bash)のコマンドをAutomatorに設定して、バックアップの際にこれを毎回起動することにしました。Automator使わなくてもターミナルを起動して打てばいいのですが、アイコンをクリックするだけのほうが簡単なので…。


 rsyncの使い方はここにまとまっています。
 http://x68000.q-e-d.net/~68user/unix/pickup?rsync


 使い方は非常に簡単で、

rsync -au --delete 同期元ディレクトリ 同期先ディレクトリ


 と記述すればいい。「-a」はおすすめの設定がまとまっているオプションですが、これだけでは足りないので-uと--deleteを設定しています。「-u」は同期先にある同じ名前のファイルが同期元より新しかった場合は上書きしないというオプション、「--delete」は同期元のファイルが削除された場合は同期先のファイルも削除するというオプションですね。
 「--delete」を付けておかないと、同期元で不要になったので消したファイルが同期先ではずっと残っていたり、同期元の内部で所属するフォルダを移動したファイルは移動元と移動先の両方に存在するようになったりして、同期先の容量がどんどん増えていってしまいます。


 まず、Automatorを起動して、新規ドキュメント(Application)を作成します。


f:id:doyaling:20150216033244p:plain


 次に、(私は英語設定で使っているので)「Run Shell Script」を選択して、内容のところに上記コマンドを書くだけです。最初に「cat」って入っているのは消して大丈夫です。


f:id:doyaling:20150216033227p:plain


 私は「4TB_Main」という名前の外付けHDDから「4TB_Backup」という名前の外付けHDDに同期したいので、

rsync -au --delete /Volumes/4TB_Main/ /Volumes/4TB_Backup/


 と書きます。これだけ。
 
 

アクセス権のエラーに対応する

 ところがこれをAutomatorに設定して起動すると、エラーが出ました。


f:id:doyaling:20150216032656p:plain


 エラーの内容を確認するため、ターミナルから打ってみました。ターミナルから打つときは、「-v」オプションを付けることで、処理内容の履歴がみれます。ここのエラーの情報も出てきます。

$ rsync -auv --delete /Volumes/4TB_Main/ /Volumes/4TB_Backup/
building file list ... rsync: opendir "/Volumes/4TB_Main/.DocumentRevisions-V100" failed: Permission denied (13)
rsync: opendir "/Volumes/4TB_Main/.Trashes" failed: Permission denied (13)
done
IO error encountered -- skipping file deletion
(中略)
sent 39781500 bytes  received 576 bytes  533987.60 bytes/sec
total size is 1859690882822  speedup is 46746.95
rsync error: some files could not be transferred (code 23) at /SourceCache/rsync/rsync-45/rsync/main.c(992) [sender=2.6.9]


 まぁ私はこんなのを見てもあまり意味がわからないので、とりあえず最後のほうのエラーコードみたいなやつでググってみたところ、こういう解説がありました。
 http://open-groove.net/linux-command/rsync-memo/
 しかし、ここに書かれてるようにオプションを「-rlpt」にしても正常化はしませんでしたね。
 それで英語のサイトもいくつかみてみたのですが、ファイルシステムがNTFSの場合はコピー出来ないファイルがあるのでどうたらこうたらみたいな説明があった程度で、結局今回の件の解決方法は分からず。


 ただ、rsyncが上手くいかない時というのは、要するにデータの所有者だのアクセス権だのの問題が起きているらしいという雰囲気はわかりました。


 たぶんですね、さっきの実行結果の中で、「opendir "/Volumes/4TB_Main/.DocumentRevisions-V100" failed: Permission denied (13)」とか「opendir "/Volumes/4TB_Main/.Trashes" failed: Permission denied (13)」とか出ていたところから推測するに、外付けHDDのボリューム(/Volumes/4TB_Main/)の直下にあるシステムファイルの類が、パーミッション(アクセス権)*1の不足によってコピー出来ないという話だったと思われます。
 なので、パーミッションを与えておけばいいんでしょう。


 パーミッションの変更については、以下の頁を参考にしました。
 Linuxコマンド集 - 【 chmod 】 ファイルやディレクトリのアクセス権を変更する:ITpro
 ファイルパーミッションの変更 - WordPress Codex 日本語版
 UNIXの基礎知識・パーミッション編


 まずターミナルで、外付けHDDのボリュームに移動してから、「ls -la」*2と打って、隠しファイルも含めた全てのファイルとディレクトリの属性情報を表示します。
 すると以下のような一覧表が表示される。


f:id:doyaling:20150217013010p:plain


 一番左のrとかwとかxとかが並んでいるところパーミッションですね。見方は上記のリンク先に書いてありますが、1文字目が「ファイルかディレクトリか」を表していて、ディレクトリなら「d」になり、ファイルだと「-」になっている。で、2文字目からは3文字単位で、「所有者のパーミッション」「グループのパーミッション」「その他の人のパーミッション」が並んでおり、この3文字の固まりは「読み(r)」「書き(w)」「実行(x)」を表している。
 たとえば「.DS_Store」は「-rwxr-xr-x」なので、これはファイルであって、所有者には読み書き実行が全て許されているが、グループとその他のユーザには読みと実行しか認められていない。


 で、rsyncを実行するのは所有者なので、たぶん所有者に「r」が許されていないファイルがコピーできなくて問題になるんじゃないでしょうかね。実際、「.DocumentRevisions-V100」と「.Trashes」は「r」が許されていません。
 まぁ、ゴミ箱なんて同期する必要がないとも思いますが、まるごとコピーするのが目的なので、ボリューム内の全てのファイルについて、「所有者はrwx、グループとその他はr-x」という設定に変えておきます。(1個1個設定してももちろんいいんだと思います。)
 ネットワークに繋がってたりするとアクセス権を安易に緩めるのもヤバイ気がしますが、私の場合は大丈夫でしょう、たぶん(よく分かってない)。
 「rwx」は数字の7、「r-x」は数字の5が対応しているので、

chmod -R 755 /Volumes/4TB_Main/
chmod -R 755 /Volumes/4TB_Backup/


 としておきました。「-R」は「再帰的に変更」ってやつで、配下のファイル・ディレクトリにすべて適用するという意味のオプションです、たぶん(よく分かってない)。


 以上のように設定してからrsyncを再度試したところ、めでたく、エラーが起きなくなりました!


 あとは、「HDD_Sync」と名づけて保存したアプリをクリックして、


 f:id:doyaling:20150216032723p:plain:w280


 歯車の表示が消えるまで待ってれば同期が完了します。


 f:id:doyaling:20150216032736p:plain:w400


 さらに、↓に説明されているような手順で、たとえば毎日朝3時に同期するみたいなスケジュールを組んでおくこともできますね。(今はiCalではなくCalendarですが。)
 iCal + automator + transmitでFTPアップ自動化のスケジュールを組んでみた|arataman.com|それはまさしくヘルシー、それはあらたまんの歩んだ軌跡
 
 

ファイル名長すぎるというエラー(追記)

 上手くいったとおもったのですが、同期が終了するのを待っていたら、以下のようなエラーが起きていました。

rsync: recv_generator: failed to stat "/Volumes/4TB_Main/01_Working/?\#207??\#202\#212?\#234??\#203??\#233??\#220?\#233??\#215/91_?\#220?\#224?\#201\#213?\#202\#211/?\#202??\#202??\#203??\#203?F?\#203??\#203\#236?\#202??\#203\#213?\#203??\#203??\#203??\#200\#201?\#203??\#202??\#202??\#202\#231?\#203??\#202??\#203??\#202??\#202\#231?\#202??\#203??\#203\#210?\#203??\#217?\#214永?\#230\#237?\#210訳?\#211?\#217?\#225?谷?\#235?\#200?\#210解説?\#211?\#200\#216?\#237??\#201??\#201\#204?\#201\#213?\#201??\#201\#227?\#201??\#200\#214?\#206\#215?\#231??\#230\#216?\#200\#215?\#201\#225?\#202\#214?\#201\#237?\#201\#213?\#200\#225?\#202??\#203??\#202??\#202??\#203??\#203\#210?\#202\#231?\#203??\#202??\#233??\#233?館?\#201\#213?\#202\#211?\#202??\#203??\#202??\#203??\#203\#215?\#203\#203?\#203\#210?\#201??\#201??\#202\#231?\#200\#225?\#200\#217?\#227??\#214BP社.pdf": File name too long (63)


 こういうものなんですが、文字化けしてるのはとりあえず措いといて、ファイル名が長すぎるよと。
 いや、そう言われても、OS上で普通に認められている長さのファイル名しか付けてないはずなのですが……rsyncの時にはそれよりも制限が厳しいんですかね?
 よくわかりませんが、このエラーがたくさん(といっても10ファイルぐらい)出ていたので、仕方なく1個1個ファイル名を短めに変更していったら、一応エラーは出なくなりました。


 ところで上記の文字化けは何とかならないんでしょうか。
 ファイル名はUTF-8のはずで、ターミナルもUTF-8に設定しているし、このへんを参考にbash_profileに

export LANG=ja_JP.UTF-8
export LESSCHARSET=utf-8


 という2行は書きましたが、解決せず・・・。
 ふつうにフォルダを移動したりファイルを開いたりする分には、日本語でできてるんですが、rsyncの処理結果の部分だけ文字化けしてしまいます。
 上記の作業では、ファイル名の中に英数字の部分もあるので、それを頼りに「どのファイルのファイル名が長すぎるのか」を特定してGUIでファイル名変更しましたが。

*1:Mac OSを日本語設定で使ってると「アクセス権」と呼ばれていると思いますが、英語設定だとPermissionなので分かりにくいですね。ディスクユーティリティの「アクセス権の修復」も英語では「Repair disk permissions」です。

*2:-lはファイルの詳細情報を表示するオプション、-aは隠しファイルも表示するオプション。