Unison
Unison は Unix ライクなオペレーティングシステム (Linux, macOS, Solaris) や Windows で動作する双方向性のファイル同期ツールです。ファイルやディレクトリの複製を別々のホスト (あるいは同一ホスト上の別々のディスク) に保存して、それぞれ別個に変更を加えて、後から複製の変更を相互に持ち寄って最新状態にすることができます。どんなシステムでもホストにすることが可能です。
目次
インストール
公式リポジトリから unison をインストールしてください。CLI, GTK+, GTK+ 2.0 のインターフェイスが入っています。
設定
Unison を使用するには、プロファイルを作成する必要があります。
GUI
GUI で Unison を設定するには次を実行:
$ unison-gtk2
手動
もしくは、~/.unison
にプロファイルを手動で作成して、以下の行をデフォルトの設定ファイルである ~/.unison/profilename.prf
に追加してください。
同期するルートディレクトリを定義:
root=/home/user/
ファイルを同期する先のリモートディレクトリを定義:
root=ssh://example.com//path/to/server/storags
任意で、SSH にわたす引数を指定:
sshargs=-p 4000
同期するディレクトリとファイルを定義:
# dirs path=Documents path=Photos path=Study # files path=.bashrc path=.vimrc
無視するファイルも定義できます:
ignore=Name temp.* ignore=Name .*~ ignore=Name *.tmp
使用方法
プロファイルを設定したら、次のコマンドで同期を開始できます:
$ unison profilename
もしくは GUI ツールを使用してプロファイルを選択してください:
$ unison-gtk2
Unison のインターフェイスでは進捗や変化を見ることができます。
バージョンの不適合
Unison を正しく機能させるには、全てのクライアントに同じバージョンをインストールする必要があります。あるコンピュータにインストールされているバージョン 2.40 で、一方、他のマシンではバージョンが 2.32 だったりすると、相互に同期することができなくなります。バージョンが一致しない2つのマシンだけでなく、全てのコンピュータでディレクトリを同期することが不可能になります。
また、Unison バイナリをコンパイルする OCaml のバージョンも合わせる必要があります。https://groups.yahoo.com/neo/groups/unison-users/conversations/topics/11439 を参照。バージョンが異なるとヘテロジニアスなネットワークで Unison が使えなくなってしまいます。
多くの Linux ディストリではリリースが途切れ途切れなので、Unison のバージョンが古い可能性があります。一方、Arch Linux は Extra リポジトリで最新のバージョンを提供しています。AUR には非公式な PKGBUILD としてバージョン 2.32 (unison-232AUR[リンク切れ: アーカイブ: aur-mirror]), 2.27 (unison-227AUR[リンク切れ: アーカイブ: aur-mirror]), 2.40 (unison-240-compatAUR) が存在し、複数のディストリを使っている場合に Unison を既存の環境と一緒に使うときに有用です。
Tips and tricks
人間の時間と手間を省く
十分なスクロールバッファが確保できるターミナルエミュレータで unison を動作させる場合、変更箇所が衝突するたびに確認を要求するのは何の意味もありません。auto
オプションを true に設定することで確認を表示しないようにできます。
diff の出力を読みやすくする
unison のデフォルトの diff コマンドは diff -u CURRENT2 CURRENT1
です。このコマンドの出力を確認するとき、左から右に変更があったり ('>')、逆に右から左に変更があると ('<')、どこが変更されるのか分かりにくいのが難点です。以下の設定を使うことでそれが分かりやすくなります: '>' が適用される行には全て '>' が付くようになります:
diff = diff -u CURRENT2 CURRENT1 | perl -pe 's/^\+/>/; s/^\-/</'
Emacs でマージ
Unison には外部のマージプログラムを使って衝突する2つのファイルのマージを手助けする機能が存在しますが、デフォルトではプログラムが設定されていません。マニュアルには以下のように設定することが提案されています:
merge = Name *.txt -> emacs -q --eval '(ediff-merge-files-with-ancestor "CURRENT1" "CURRENT2" "CURRENTARCH" nil "NEW")'
マージコマンドはターミナルから実行することができないため、上記を使うには X で Unison を実行する必要があります (Emacs: "standard input is not a tty")。また、Unison は CURRENT1 などの変数をシングルクォートで囲まれたファイル名に置き換えます。そのため、"(ediff-merge-files... \"CURRENT1\" ...)" のようにダブルクォートを使用すると上手くいきません。
CURRENTARCH 変数は共通祖先による 3-way マージを使用することを Unison に指定します。最後の同期で "backupcurrent" が設定されていた場合にのみ 3-way マージになります。通常の 2-way マージをターミナルで実行したい場合、以下の設定を使ってください。ediff.el ではなく emerge.el を使っています:
merge = Name {*,.*} -> urxvt -e emacs -nw -q --eval '(emerge-files nil "CURRENT1" "CURRENT2" "NEW")'
CURRENTARCH の代わりに CURRENTARCHOPT 変数が使われた場合、Unison は可能なときに共通祖先を使って、そうでない場合は (変数に空の文字列を設定して) 2-way マージにフォールバックします。シェルスクリプトで検知することが可能です。例:
merge = Name {*,.*} -> unison-merge-files CURRENT1 CURRENT2 NEW CURRENTARCHOPT
unison-merge-files
を上記のように定義した場合:
#!/bin/sh CURRENT1=$1 CURRENT2=$2 NEW=$3 CURRENTARCHOPT=$4 EMACS="urxvt -e emacs -nw" if [ x$CURRENTARCHOPT = x ]; then $EMACS --eval "(emerge-files nil \"$CURRENT1\" \"$CURRENT2\" \"$NEW\")"; else $EMACS --eval "(emerge-files-with-ancestor nil \"$CURRENT1\" \"$CURRENT2\" \"$CURRENTARCHOPT\" \"$NEW\")"; fi
一般的な設定の同期
システム (サーバー, ワークステーション, ノートパソコン, スマートフォンなど) 上の設定ファイルを同期する場合、基本的な部分 (キーバインドやシェルのエイリアスなど) だけを別の設定ファイル (例: .bashrc_common
) に分割して、変更がある部分 (アプリケーション特有の設定やセキュリティに関する設定など) だけを同期すると良いでしょう。
参照
- Wikipedia:Unison (file synchronizer)
- 公式ウェブサイト
- Yahoo! ユーザーグループ
- Liberation through data replication by Philip Guo
- Setting up Unison for your mom by Philip Guo
- Replication using Unison on TWiki