分からんこと多すぎ

何故か就職できたので技術磨く。一人前の多重線形代数使いを目指しつつ、機械学習、データマイニングをやる

MacOSXで無限容量のDropbox作った

概要


MacOSX側でファイルの変更(作成・変更・削除)があった場合、それを検知し、別のPC(サーバ)と同期する。
ファイルはMac側とサーバ側の両方に実体として残る。
バックアップ、ログなども取れるが、今回は使用しない。

  • メリット
    • 容量が事実上無制限
  • デメリット
    • ファイル数が増えると遅くなる
    • 複数PCを同期し続けたい場合、サーバを常時立てておく必要がある

仕組み



  1. Macのログイン時にスクリプトを起動する

  2. スクリプト内でfswatchというコマンドを用いてファイル変更を監視する

  3. ファイルの変更があった場合、unisonというコマンドで同期する

unison


unisonとはファイル双方向同期用のコマンドである。
rsyncなどとは異なり、コピー元、コピー先という指定はない。
その代わりに、クライアントとサーバのファイルを両方共見て、更新が新しい方のファイルを両方に上書きする。
(もちろん設定による優先順の変更、同期するか否かの確認あり)

これをクライアント(Mac)とサーバ(FreeBSD)に導入する。
なお、両方共バージョンが一致していないと上手く動かないので、注意する。

詳しく知りたい人は、このあたりを見ると良い。
unison-manual-ja | 88171.net
Linux - Notes, Tricks, Tips
Unison [KamonoWiki]

導入


クライアント側

brew install unison
unison -version

今回はunison version 2.40.102だったので、これをサーバに導入する。

サーバ側

cd /usr/ports
make search unison-2.40
make install unison-2.40

設定


unisonには色々オプションがある。
使うたびに一々書いていられない。
なので、mac側の~/.unison/hogehoge.prfという拡張子のファイルを書く。
このようにすると、unison hogehogeという風にコマンドを実行した際に、その設定が参照されるようになる。

私はremote.prfというファイルに、以下のように記述している。

remote.prf

# Unison preferencele
# option
# times ファイルの時刻をコピー元のままに保存する
times = true
# prefer newer 新しい方を優先する
prefer = newer
#新規作成ファイルはユーザに同期如何を問わない
auto = true
#ファイル更新日時による更新有無の判定
fastcheck = true
#エラー以外の出力停止
silent = true

# ローカルとリモートの指定
# 実際に同期したいディレクトリはpathで指定するため、全体を指定
root = /Users/クライアントユーザ名/同期したいディレクトリ(最上位)
root = ssh://サーバユーザ名@サーバ名//同期したいディレクトリ(最上位)
#ここはログイン名@サーバ名//usr/mynameみたいに/を重複させる必要がある

# 実際に同期したいディレクトリを指定(複数可)
#path = /usr/myname/同期したいディレクトリのパス

#無視して欲しいファイルを指定
ignore = Name *~
#ignore = Name .*~
ignore = Name .bak

#Keep a backup copy of the entire replica
#backup = Name *

クライアント側で

unison remote

を実行してファイルが同期されたら成功

ssh公開鍵設定


unisonは見ての通り、sshを利用して通信をしている。
なので、unison remoteとコマンドを叩いて同期すると、そのたびにパスワードを要求される。
面倒でやってられないので、公開鍵を利用して勝手にパスワードを読み取ってくれるようにする。

あと、クライアントとサーバでのユーザ名が違うと、ssh-keygen(公開鍵の作成)だけでは上手く動かない。
そういう人は、サーバに対してユーザ名を指定して、公開鍵を参照してくれるようにする必要がある。
clmemo@aka: 複数の public key を .ssh/config で管理する

サーバ側(今回はrsa鍵)

ssh-keygen -t
#指定は全て何も記入せずにEnter
scp ~/.ssh/id_rsa ユーザ名@クライアント名:/Users/ユーザ名/.ssh/id_rsa
scp ~/.ssh/id_rsa.pub ユーザ名@クライアント名:/Users/ユーザ名/.ssh/id_rsa.pub

クライアント側

cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
chmod 600 ~/.ssh/*
#パーミッションが600でないとsshに怒られる

そして、クライアント側で~/.ssh/configファイルを作成する

config

Host サーバ名
  HostName サーバ名
  User サーバユーザ名
  IdentityFile ~/.ssh/id_rsa
ssh サーバ名

でログイン出来たら成功。

さらに

unison remote

でパスワードを聞かれずにファイルが同期できればOK

fswatch


fswatchとは、Mac用のファイル変更監視コマンドである。
変更を監視し、変更があった場合に指定されたコマンドを実行してくれる。

./fswatch /some/dir "echo changed" 

こういう風に指定すると、/some/dir以下でファイルの変更があった場合に、changedとechoされる。

ダウンロード元はここ。
alandipert/fswatch · GitHub
ダウンロードしてzipを解凍する。

ディレクトリ内で

make

すればfswatchコマンドが出てくるので、それを適当にパスが通ったディレクトリに置く。

ログイン時にコマンド起動


[システム環境設定] -> [アカウント] -> [ログイン項目]
で.commandというファイルを指定すると、ログイン時にそのコマンドが実行される。

なので、commandファイルを作成する。

詳しくはここ。
ログイン時のスクリプト起動 - メメメモモ

ちなみに他にも色々賢い方法は存在するが、これが一番簡単。
自分のようなサーバのイロハも分からない情弱ユーザには、このあたりが限界だった。
賢い人もっとうまいやり方を教えて下さい。

auto_unison.command

fswatch ~/unidir 'unison remote'&

あとはログイン項目の項から設定をすれば良い。

完成!