Unisonマニュアル私的日本語訳
クールなファイルシンクロナイザ、Unisonのマニュアルのクールでない私的な日本語訳です。 対象のバージョンはだいぶ古めです。
内容は一切保証しません。 誤訳や解釈間違いなどありましたら教えてください。
概要
UnisonはUnix及びWindowsに対応したファイルシンクロナイザです。 異なるホスト(もしくは同じホスト上の異なるディスク)に別々に保存され変更されたレプリカ(訳注: ここでは同期の対象となるファイルやディレクトリ、もしくはそれら全体を指します)の間で、それらの内容を同期させることができます。
Unisonは、CVSやPRCS等のリビジョン管理システム、Coda等の分散ファイルシステム、rsync等のミラーリングツール、そしてIntellisyncやReconcile等の他のシンクロナイザと多くの共通した特徴を備えていますが、同時に以下のような違いもあります。
- UnisonはWindows(95/98/NT/2K)とUnix(Solaris/Linux etc.)の両方のプラットホーム上で動作します。 それだけでなく、プラットホームを越えて動作することも出来ます。 つまり、Windowsの動いているラップトップとUnixで稼働しているサーバの間でファイルを同期させることができるわけです。
- 組み込みのファイルシステムと異なり、Unisonはユーザレベルで動作します。 カーネルをハックする必要はありませんし、どちらのホストにおいても管理者権限は必要ありません。
- 他の一方向性のミラーリングツールやバックアップユーティリティと異なり、Unisonは両方のホストそれぞれについて(双方向に)ファイルの更新を行なうことが出来ます。 一方のホストでのみレプリカが変更された(つまり衝突しない更新である)場合には自動的にもう一方のホスト上のファイルも更新し、もし変更が双方のレプリカに対して行なわれている場合にはそれを検知し、ユーザに通知します。
- Unisonはネットワークに接続された任意のホスト間で実行できます。 ソケットによるダイレクトなTCP/IP通信でも可能ですし、rshやsshで通信をトンネルすることもできます。 PPP接続のように細い回線でも十分に動作します。 巨大なファイルの一部分のみを更新するような場合には、rsyncのものに似た圧縮プロトコルによって最適化を行ないます。
- Unisonには明確で詳細な仕様があります。
- Unisonはエラーに強く作られています。 プログラムの異常終了や突然の回線断の場合にも、常に双方のレプリカの状態を保ちます。
- Unisonはフリーです。全てのソースコードはGPLの下で公開されています。
序文
人々
- Benjamin PierceがUnisonプロジェクトのリーダーを務めています。 Zhe Yangはプロジェクトのフルタイムの研究者です。
- 現バージョンのUnisonはTervor Jim、Benjamin Pierce、Jerome Vouillon、Sylvain Gommier、Matthieu Goulayにより設計・実装されました。
- Norman RamseyとSylvain Gommierにより、rsyncプロトコルの実装がなされました。 これはAndrew Tridgellの論文が元となり、rsyncからインスパイアされました。
- ミラーリング及びマージ機能はSylvain Royにより実装されました。
- Jacques GarrigueがオリジナルのGTKバージョンのUIに寄与しました。
- Javaによるシンクロナイザのプロトタイプの実装にSundar Balasubramaniamが寄与しました。 Insik ShinとInsup Leeはこの実装へのデザイン案に寄与しました。 Cedric Fournetは更に以前のプロトタイプに寄与しました。
ライセンス
Unisonはフリーソフトウェアです。GNU GPLの下に変更や再配布をして構いません。 詳しくはUnisonのソースに含まれるCOPYINGを参照してください。
バグレポート
Unisonが思ったように動かない場合、いくつかの踏むべき手順があります。
- まず、Unisonに
-debug allオプションをつけて実行してみてください。 Unisonが内部でどういった動作をしているかが表示されます。 どこで問題が発生しているか見極めるのに有効でしょう。 - 次にunison-help@cis.upenn.eduにバグレポートを送ってください。
その内容がバグフィックスの役に立ちます。
その際、Unisonのバージョン(
unison -versionで表示されます)、どのようなマシンでUnisonを実行しているか、-debug allオプションをつけて実行した際の出力、そして発生した問題に関するできる限り詳細な情報を含めることを忘れないでください。 - もし他のユーザにも同様の問題が発生しているのではないかと思う場合(例えばバグではなく設定の問題に思える場合)、ユーザのメーリングリスト(unison-users@groups.yahoo.com)で役立つアドバイスがもらえるかもしれません。
支援
Unisonは開発者にとって片手間のプロジェクトです。
私たちは、自分たち自身やコミュニティにとって役に立つ何かを作ることが楽しくて開発を続けています。
が、私たちには他にもやらねばならない仕事があります。
もしあなたがUnisonを気に入り、開発に手を貸したいと思ったならば、私たちはいつでも歓迎します。
コードの体系などより詳しいことは、ソースに含まれる CONTRIB というファイルを参照してください。
もしハックする気がなくても、単にあなたがどのようにUnisonを好きなのかを教えてくれるだけでも私たちへの支援になります。 例えば「Unisonを使っています。しっかり動作してくれます」とか「使ってみましたが、欲しかったものとは少し違います。なぜなら‥‥」といったような短い文章でも、私たちにとっては有用な情報です。
インストール
Unisonのインストールは非常に簡単です。以下の手順に従うだけで、ものの数分でUnisonが利用可能になるでしょう。
Unisonは
- 端末やスクリプトから用いるのに適した、シンプルなコマンドラインユーザインタフェース(CUI)
- GTKを用いた洗練されたグラフィカルユーザインタフェース(GUI)
の2つのユーザインタフェース(UI)を備えています。
ファイルを同期させたい全てのマシンにUnisonをインストールする必要があります。 ただ、GUIを使いたい場合には実際にUIを表示するマシン(つまりクライアントとして使うマシン)にのみGUIバージョンのUnisonをインストールするだけで構いません。 その場合も、サーバマシンにインストールされているのがCUIバージョンであるかGUIバージョンであるかに関係無く、きちんと動作します。
ダウンロード
もしマシンのアーキテクチャに合ったビルド済みのバイナリが手に入るなら、それをダウンロードして(コマンドラインから使うのであれば)パスの通ったディレクトリに放り込むか、(直接クリックして使いたいなら)デスクトップに置くだけでOKです。
GUIバージョンのバイナリ(これはファイル名に gtkui を含みます)は、実際には2種類のUIを提供します。
デフォルトではGUIで、コマンドラインで
unison -ui text
を指定するとCUIで動作します。
CUIバージョンのバイナリ(同様にファイル名に textui を含みます)はCUIのみを提供します。
アーキテクチャに合ったビルド済みバイナリが見つからないときは、自分でソースからビルドする必要があります。 数は少ないですが、有志による移植版も存在します。
本当に実行可能なファイルをインストール出来たか確認しましょう。 ファイルをクリックして実行してみるか、コマンドラインから
unison -version
と打ってみましょう。
Unisonはいろいろな場面で使うことが出来ます。
- 同一マシン上のディレクトリ間で
- 異なるマシン間をダイレクトなTCP/IP通信で
- 異なるマシン間をrshやssh越しで
もしrshやssh越しで利用することを考えているなら、rshやsshを別途インストールする必要があります。
実行
Unisonのインストールが終わったら、マニュアルのチュートリアルを読むか、
unison -doc tutorial
と打ってみましょう。
アップグレード
アップグレードも簡単です。 古いバイナリを新しいバージョンのバイナリに置き換えるだけです。
アップグレードの前に一度古いバイナリで完全にファイルを同期させておいた方が良いでしょう。 Unisonは各レプリカの状態を記憶するためにアーカイブファイルを生成しますが、新しいバージョンではそのファイルのフォーマットが変わっていることがあります。 この場合、古いアーカイブファイルは単純に無視されます(が、古いアーカイブファイルは削除はされません。つまりUnisonを古いバージョンに戻せば、古いアーカイブファイルがそのまま利用可能なわけです)。 つまり、古いバージョンで同期させずに新しいバージョンを動作させた場合、全ての更新が衝突したと判断され、手作業で同期させねばならなくなるわけです。
移植版
何人かの人が特定のアーキテクチャ向けのビルド済みのバイナリや、インストールを容易にするスクリプトを提供してくれています。 私たちが管理しているわけではなく、その内容に保証はありませんし、必ずしも最新版に追随してはいませんが、きっと役に立つことでしょう。 現時点で手に入るものを挙げておきます。
- Dan PellegがUnisonをFreeBSDに移植しました。つまりportsからUnisonをインストールできます。
cd /usr/ports/net/unison; make && make installしましょう(実行する前にportsが最新であることを確認しましょう。FreeBSD向けにコンパイルされた最新のUnisonが利用できます)。 FreeBSD向けのバイナリはhttp://www.freebsd.org/cgi/ports.cgi?query=unison&stype=allからも手に入ります。 - Andrew PittsがLinux-PPCプラットホーム向けのバイナリを作りました。 ftp://ftp.cl.cam.ac.uk/papers/amp12/unison/から手に入ります。
- Robert McQueenがDebian向けのパッケージを管理しています。 詳しくはhttp://packages.debian.org/testing/non-us/unison.htmlを参照してください。
- Chris CocoscoがSGI IRIX(6.5)向けのバイナリを提供しています。 http://www.bic.mni.mcgill.ca/users/crisco/unison.irix/から手に入ります。
ビルド
ビルド済みのバイナリが手に入らない場合は、ソースからコンパイルする必要があります。 ソースはバイナリと同じ場所から手に入ります。
基本的に、OCamlが移植され、Unixモジュールが完全に整った環境であればUnisonは動くはずです。 特に様々なバージョンのWindows(98、 NT、 2000)及びUnix(Solaris、 Linux、 FreeBSD、 MacOS X)、更に32bit及び64bit環境でテストされています。
UnisonはMacOS 8及び9では(恐らく今後も)動きません。
Unix
Objective Caml compiler(バージョン3.04以降)が必要です。
オフィシャルサイトから入手可能です。UnixシステムにOCamlをインストールするのは非常に簡単です(クイックスタート‥‥多くのシステムでは以下のコマンドでコンパイラをインストールできます。まず make world opt、次に su でrootになり、make install)。
ソースに含まれる手引きを参照してください。
バイトコードコンパイラに加えてネイティブコードコンパイラもビルドしたいと思うかも知れませんが、これは絶対必要な条件ではありません。
また、GNU makeが必要です。
make --version でGNUバージョンのmakeがインストールされていることを確認しましょう。
OCamlのインストールが終わったら、Unisonのソースを入手して展開しましょう。 展開してできたディレクトリに移動し
make UISTYLE=text
と打てばunisonという名前で実行可能ファイルが作成されるはずです。
./unison と打って実行できるか確認しましょう。
上手くいっていればusageが表示されるはずです。
GUIバージョンをコンパイルしたい場合は、以下の2つも用意しておく必要があります。
- GTKライブラリ
- GTKの1.2以降が必要です。 http://www.gtk.org/から入手できますし、多くのUnixでそのシステムに応じた方法でインストールすることもできます。
- LablGtk
- Lablgtk2(1.3.3で動作が確認されています)が必要です。
http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgtk.htmlから開発版のtarballを入手し、展開しましょう(クイックスタート‥‥
make configure、次にmake、make opt、そしてsuしてmake install)。 次にUnisonをビルドしましょう。 パスの設定が正しければmake UISTYLE=gtkと打つとunisonという名前で実行可能ファイルが生成されます。
- Lablgtk2(1.3.3で動作が確認されています)が必要です。
http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgtk.htmlから開発版のtarballを入手し、展開しましょう(クイックスタート‥‥
もしこの方法がうまくいかない場合でも心配は無用です。 UnisonはCUIでも十分に動作しますから。
Unisonの実行可能ファイルをパスが通ったディレクトリに入れるか、ファイルのあるディレクトリにパスを通すかしましょう。
Windows
どのバージョンのWindowsでも配布されているバイナリファイルは動作しますが、ソースからビルドしたいという人もいるでしょう。
バイトコードバージョン
Unisonをビルドするのに、シンプルですが遅い方法はバイトコードバージョンをビルドする方法です。 WindowsバージョンのOCamlコンパイラの3.04以上をインストールしましょう。 次にUnisonのソースを入手して
make UISTYLE=text NATIVE=false
とタイプすることで、バイトコードをコンパイルできます。
unison.exe というファイルができているはずです。
ネイティブコードバージョン
より効率的なネイティブバージョンのUnisonをコンパイルするには、2つの方法があります。 両方ともOCammlの3.04以降とCygwinが必要です。 これらの方法の違いはCコンパイラです。 MS Visual C++ を用いるかCygwinのGNU Cを用いるかです。
違いは何でしょうか。
- MSVCを用いる方法でのみ、スタティックリンクされたUnisonの実行可能ファイルを生成できます。
- CygwinのGNU Cを用いる方法はフリーなソフトウェアのみで実現できます。
INSTALL.win32-msvc と INSTALL.win32-cygwin-gnuc というファイルに、それぞれの方法でビルドする手順が書かれています。
インストールオプション
ソースアーカイブの中の Makefile にUnisonがどのようにビルドされるかをコントロールできるスイッチが含まれています。
有用ないくつかを紹介します。
NATIVE=trueで、OCamlコンパイラでバイトコードバージョンより若干速く動作するネイティブバージョンのUnisonをビルドできます。 配布版のバイナリではこのオプションを使っています。make DEBUGGING=trueでデバッグシンボルを生成します。make STATIC=trueで(ほとんど)スタティックにリンクされたバイナリを生成できます。 ポータビリティのため、配布版のバイナリではこのオプションを使っています。
チュートリアル
下準備
UnisonはCUIとGUIの2種類のUIを提供します。 CUIは端末や、スクリプトから呼び出して使うのに適します。 GUIはよりインタラクティブな操作を可能にします。 このチュートリアルを読み進む上で、どちらのバージョンを使っても構いません。
コマンドラインオプションはそれぞれのバージョンで異なります。 GUIバージョンのUnisonは直接クリックするだけで使えますが、それにはちょっとした設定が必要です。 このチュートリアルでは、CUIバージョンを使うという前提で話を進めます。
Unisonは一つのマシン上の異なるディレクトリのファイルの同期を取ることも出来ますし、ネットワーク上の異なるマシンの間で同期を取ることも出来ます(この場合、両方のマシンでそれぞれ同じプログラムが走ります。それらの違いは、どちらがUIを表示するかだけです)。 一つのマシン上で同期を取る場合には、そのマシンをクライアントと呼びます。 2台のマシンの間で同期を取る場合には、それぞれクライアントとサーバと呼ぶことにします。
ローカルで使う
まずクライアントで、2つのディレクトリのファイルの同期を取る設定をしましょう。
インストールは済んでいますか?済んでいないならインストールのセクションを参照してください。
テスト用に a.tmp というディレクトリを作りましょう。中には適当なファイルやディレクトリを作っておきます。例えば
mkdir a.tmp
touch a.tmp/a a.tmp/b
mkdir a.tmp/d
touch a.tmp/d/f
こんな感じです。次に a.tmp を b.tmp にコピーしましょう。
cp -r a.tmp b.tmp
では、a.tmp と b.tmp の同期を取ってみましょう。
ただし、今回はそれぞれ同じなので、Unisonは特に変更を行ないません。
しかしUnisonは現在の状態を記憶し、次回どのファイルやディレクトリが更新されたかを検知します。
unison a.tmp b.tmp
と打ってみましょう。
CUIモードの場合:
- 双方のレプリカが同じである旨が表示され、プロンプトが返ってきます。
GUIモードの場合:
- 双方のレプリカが同じである旨が表示された大きなウィンドウが開くでしょう。 FileメニューからExitを選択して、コマンドラインに戻りましょう。
次に、a.tmp と b.tmp にそれぞれ違う変更を加えましょう。例えば
rm a.tmp/a
echo "Hello" > a.tmp/b
echo "Hello" > b.tmp/b
date > b.tmp/c
echo "Hi there" > a.tmp/d/h
echo "Hello there" > b.tmp/d/h
もう一度Unisonを実行しましょう。
unison a.tmp b.tmp
今度は更新されたファイルが表示されるはずです。 どちらか一方のレプリカのみで変更されたファイルには、そのファイルがどちらに更新されるかを示す(新しい方から古い方への)矢印が表示されます。 例えば
<--- new file c [f]
この場合2番目のレプリカでのみ c という新しいファイルが作られ、デフォルトでは1番目のレプリカにファイルがコピーされることを示しています。
Unisonのデフォルトに従う(follow)には、プロンプトで f と打ちます。
もし両方のレプリカが更新され、その内容が異なる場合、その更新は衝突したと表現します。 更新が衝突した場合、Unisonは以下のようなプロンプトを表示して、どちらのレプリカで更新すべきか問い合わせます。
new file <-?-> new file d/h []
デフォルトでは、双方のレプリカは更新されず、そのまま保存されます。
(この例における b というファイルのように)双方のレプリカが更新されているが内容が同じである場合、更新は必要ないためUnisonは何も表示しません。
単にUnison内部で、双方のファイルが最新であると記憶されるだけです。
この更新状況の表示方法はCUIとGUIどちらのバージョンでも同様に用いられます。 唯一の違いは、ユーザがUnisonのデフォルトの動作に従うか否かを決定する操作方法のみです。
CUIの場合:
- 変更されたそれぞれのファイルの状態が順番に表示されます。
2つのレプリカに含まれるあるファイルの内容が同一でなかった場合、UIはその変更をどのように更新するかを問い合わせます。
デフォルトの動作が(矢印で)示されている場合、エンターを叩くだけで次に進むことができます。
違う操作をしたい場合、
<(もしくは>)を叩くことで、右から左(もしくは左から右)の方向への更新を強制することができます。 もしくは/を叩いて更新をスキップし、双方のレプリカをそのままにしておくこともできます。 変更されたファイルのリストの最後に達すると、Unisonは選択された更新を本当に行なうかもう一度問い合わせます。 - Unisonのプロンプトが表示されている際、
?を叩くことでヘルプを表示させることができます。
GUIの場合:
- メインウィンドウにどちらか(もしくは両方)のレプリカで変更されたファイルが全てリストアップされます。
デフォルトの動作から変更する場合(もしくはデフォルトの動作が指定されていない場合)、まずファイル名をクリックするか上下のカーソルキーを使ってファイルを選択します。
次に左カーソルか
<(もしくは右カーソルか>)を叩くことで、右から左(もしくは左から右)へファイルを更新させることができます。 - 全てのキーボードコマンドはUIの上部にあるメニューから選択して実行することもできます。 (逆に、それぞれのメニューアイテムには、あればキーボードショートカットが併記してあります。)
- メインウィンドウに表示されている更新動作の内容に納得したら、Goボタンをクリックして実際に更新を実行してください。 更新が完了したものから順に、それぞれのファイル名の隣にチェックサインが表示されます。
リモートで使う
次に、Unisonでネットワーク越しにレプリカの同期を同期させる方法を見てみましょう。
インストールのセクションを参考に、サーバにもUnisonをインストールしましょう(サーバにはCUIとGUIのどちらのバージョンをインストールしても構いません。サーバ側のUnisonはUIを表示する必要が無いからです)。 実行可能ファイルにパスが通っていることを確認してください。
サーバにインストールされたUnisonとクライアントのUnisonのバージョンが揃っていることが重要です。 しかしクライアントと同じバージョンのUnisonを
unison -addversionno
で呼び出すことも可能です。
Unisonをネットワーク越しに使うには2通りの方法がありますので、どちらの方法を使うか決めましょう。
- リモートシェルを使う方法
- この方法を使う場合、クライアントのコマンドラインからrshやssh等でサーバ上のコマンドを実行出来ることが必要です。 この方法はより簡単(手動でUnisonサーバプロセスを走らせる必要が無いため)で、通信路が暗号化されるsshを使えば、よりセキュアに使うことが出来ます。
- ソケットを使う方法
- この方法はクライアントとサーバの間でTCPのコネクションが張れさえすれば使えるという利点があります。 厳格なファイアーウォールが間にある場合は厳しいですが、そうでなければどこでも使うことが出来ます。
リモートシェル越しに使う
Unixで使われる標準的なリモートシェルはrshです。 sshはrshと似ていますが、通信路を暗号化するという点で、より安全です。 rshやsshでサーバとクライアントの間のコネクションを確保するには設定が必要です。 rshやsshのドキュメントを参照してください。 ここでは例としてsshを使用しますが、必要があれば適宜sshをrshに読み替えてください。
まず、サーバ側のコマンドをクライアントから実行出来るか確認しましょう。
ssh remotehost unison -version
と打って表示された内容が、クライアントで
unison -version
と打った場合の内容と同じであることを確認してください。 もし実行出来ないのであれば、(permission denied等と表示される場合は)sshの設定を見直すか、(command not found等と表示される場合には)サーバでUnisonの実行可能ファイルにパスが通っているか確認してください。
クライアントのホームディレクトリにテスト用の a.tmp というディレクトリを作りましょう。
クライアントのUnisonがサーバに接続出来るか試してみましょう。
unison -testserver a.tmp ssh://remotehost/a.tmp
ではホームディレクトリに移動して
unison a.tmp ssh://remotehost/a.tmp
と打ってみましょう。クライアントの a.tmp がサーバに転送されるはずです。
最初の同期が終わったら、a.tmp の中にファイルを作ったりファイルを更新したりして、もう一度実行してみましょう。
ローカルで実行した場合と同じような表示が出るはずです。
クライアント上とサーバ上でユーザ名が異なる場合には、コマンドラインで指定する必要があります。
unison a.tmp ssh://user@remotehost/a.tmp
注意:
-
a.tmpをサーバのホームではないディレクトリに置きたい場合、コマンドラインで絶対パスを指定出来ます。unison a.tmp ssh://remotehost//absolute/path/to/a.tmp -
サーバのUnisonのパスを明示することが出来ます。 コマンドラインオプションでは
-servercmd /full/path/name/of/unison、もしくは設定ファイルにservercmd=/full/path/name/of/unisonと追加してください。 同様に、rshやsshのパスも-rshcmdや-sshcmdで指定出来ます。
ソケット越しに使う
Unisonをソケット越しに使うには、サーバで Unisonサーバプロセスを走らせておく必要があります。 このプロセスはバックグラウンドでクライアントのUnisonからの接続を待ち受けています。
Unisonをソケット越しで使う方法は安全ではありません。やり取りするファイルの内容が平文のままネットワーク上を流れるだけでなく、世界中からそのサーバプロセスに接続して、あなたのファイルシステムの内容を読み取ってしまうことも可能なのですから!(もちろんこれにはUnisonのクライアントとサーバの間でやり取りされるプロトコルを理解していなければなりませんが、それに必要なのはUnisonのソースだけです。)
デーモンを開始させるにはサーバ上で
unison -socket NNNN
と打ちます。NNNN にはポート番号を指定します。(他のアプリケーションに使われていない番号を指定します。指定したポートが既に使われていた場合には、Unisonはエラーを表示して終了します。)
クライアントで指定された path はデーモンが開始されたディレクトリからの相対パスに変換されることに注意してください。
これはリモートシェルを用いた場合と異なります。
リモートシェルの場合、path はサーバ上のユーザのホームディレクトリからの相対パスとなります。
クライアントのホームディレクトリにテスト用の a.tmp というディレクトリを作り
unison a.tmp socket://remotehost:NNNN/a.tmp
と打って実行してみましょう。
a.tmp がサーバにコピーされるはずです(この場合、a.tmp はサーバ上の、デーモンを起動したディレクトリの中に作られます)。
最初の同期が終わったら、ファイルに変更を加えて再度実行してみましょう。
ローカルで実行した場合と同様の結果が得られるはずです。
ホームディレクトリのファイルをUnisonで同期させる
Unisonの基本的な操作に慣れたら、Unisonで普段使っているファイルを日常的に同期させたいと思うかもしれません。 これにはいくつかの方法があります。
1.(ignore で)無視するファイルを設定して一時ファイルや一方のホストのみに属するファイルを除外しながら、ホームディレクトリ全ての同期を取る。
2. 双方のマシンのホームディレクトリに shared(もしくは current でも何でも)というディレクトリを作り、同期を取りたいファイルは全てそのディレクトリに入れる。
3. 双方のマシンのホームディレクトリに(例えば)shared というディレクトリを作り、同期を取りたいファイルへのリンクをそのディレクトリに入れる。
シンボリックリンクがUnisonに透過的に扱われるように、follow 設定をする。
4. ホームディレクトリを同期を行なう基点として指定するが、Unisonにはその中の一部のサブディレクトリやファイルの同期を取るよう指定する。
これはコマンドラインで -path オプションによって指定することも出来ます。
ホームディレクトリ全体等、大きなレプリカに対して初めてUnisonを実行する際には、Unisonは全てのファイルをチェックして内部のデータ構造を記録するのに多くの時間を費します。
試しに実行してみるのであれば、コマンドラインで -path some/small/subdirectory というように小さなサブディレクトリのみを指定して、実行時間を節約するのも手です。
満足する結果が得られたら path オプションを外して実行し、Unisonがディレクトリを一生懸命漁っている間に、あなたはランチでも食べてきてください。
もしレプリカが大きく、しかもWindows上のレプリカが含まれている場合には、Unisonの実行速度が遅過ぎると感じるかもしれません(何故ならUnisonはWindows上では、実行する度に全てのファイルとディレクトリをスキャンするからです。というのもこれがWindows上で更新をチェックするのに最も安全な方法だからです)。
このような場合、fastcheck の設定を行なうのも一つの手です。
例えばラップトップとファイルサーバの間でファイルを同期させる場合のように、いつも決まったマシンからUnisonの操作をする場合、クライアント側だけの設定をするだけで済むことに気付くでしょう。 これは一方向性のミラーリングツール(例えばrdist等)を用いた場合に、常に最近レプリカに変更が加えられたマシンから操作をする必要があることと比べると、特徴的です。
もっと知る
様々な特徴について書かれたUnisonのオンラインマニュアルを手に入れるには、コマンドラインから
unison -doc topics
と打ち込むか、GUI画面のHelpメニューをクリックします。 オンラインマニュアルはこのマニュアルと基本的な内容は一緒です。
Unisonには2種類のメーリングリストがあります。詳しくはhttp://www.cis.upenn.edu/~bcpierce/unison/download.htmlを見てください。
リファレンス
ここではUnisonの詳細な特徴について触れます。
Unisonを実行する
Unisonを実行するにはいくつかの方法があります。
- コマンドラインで
unison profileと打って実行する。 Unisonは.unisonディレクトリからprofile.prfというファイルを探します。 このファイルの中でrootが2つ指定されていない場合は、Unisonはプロンプトを表示してそのプロファイルに情報を追加します。 - コマンドラインから
unison prifile root1 root2と打って実行する。 この場合Unisonはprofileを使いますが、これにはrootディレクティブが設定されていてはいけません。 - コマンドラインから
unison root1 root2と打って実行する。 これはunison default root1 root2と同じです。 - 単に
unisonと打つ(もしくはアイコンをクリックして実行しても一緒です)。 この場合、Unisonは使用するプロファイルを問い合わせます(もしくは必要があれば新たに作成します)。
.unisonディレクトリ
Unisonはそれぞれのホストのディレクトリに、様々な情報を保存します。
環境変数 UNISON が設定されている場合、その値がそのディレクトリ名として使用されます。
設定されていない場合、使用しているOSによってディレクトリ名は異なります。
Unixでは $HOME/.unison、Windowsでは、環境変数 USERPROFILE が設定されていれば %USERPROFILE%\.unison、HOME が設定されていれば %HOME%\.unison、どちらも設定されていなければ C:\.unison が使われます。
アーカイブファイルはそのレプリカのあるホストの .unison ディレクトリに作られます。
プロファイル(後述)は常にクライアントの .unison ディレクトリから探し出されます。
Unisonはそれぞれのrootについて全く異なるアーカイブファイルを保持することに注意してください。
.unison ディレクトリを丸ごと同期させることはお薦めできません。巨大なアーカイブファイルを更新に含めることになるからです。
しかし、あなたがそれを望むならそうしても安全です(.unison ディレクトリ内のプロファイルを同期させること自体は何ら問題ありません)。
アーカイブファイル
各レプリカに対するアーカイブファイルは以下の情報から計算されます。
- 全てのホストについての正確な名前。
saulのような短い名前はsaul.cis.upenn.eduのようにフルアドレスに変換されます。 - 全てのホストにおけるレプリカへのpath。 繰り返すと、相対パス、シンボリックリンク等は絶対フルパスに変換されます。
- Unisonがファイルのフォーマットを変更する際に常に更新される内部的なバージョン番号
この方法はほとんどのユーザに対して有効に機能します。 しかし、アーカイブファイルの名前を生成する方法を変更することが役に立つ場合もあります。 Unisonは2つの方法を用意しています。
ローカルホストの正確なホスト名(これは例えばどのファイルが同期されたかという情報を保存するアーカイブファイルの名前を生成するのに使われます)を調べるために、Unisonは通常 gethostname() というシステムコールを使います。
しかし UNISONLOCALHOSTNAME という環境変数が設定されている場合、代わりにその変数の値が使用されます。
これにより、ホスト名が頻繁に変わる場合(例えばラップトップをあちこち持ち歩くような場合)でもより簡単にUnisonを利用することができます。
よりパワフルな方法として、rootalias 設定を用いることができます。その設定ファイルには以下の書式の複数の行を含みます。
rootalias = //hostnameA//path-to-replicaA -> //hostnameB//path-to-replicaB
ある一組のrootに対してアーカイブファイル名を計算する際、Unisonは rootalias 設定の左側の root 設定を右側の root 設定に置き換えます。
あるホスト上の root を置き換えたい場合、以下のように追加します。
rootalias = //new-hostname//new-path -> //old-hostname//old-path
注意: rootalias 設定は危険ですので、自己責任で使ってください。
特に、1)元の root と新しいエイリアスが同じファイル群を指していること、2)元のファイル名がもう使えなくなったためにファイル名を変え、これからもそのファイル名を絶対に使わないこと、のいずれかを満たす場合のみ使用してください(元の root とエイリアスが違うファイル群を指している場合、Unisonは混乱してしまいますから)。
新しい rootalias 設定を加えたら、Unisonを何度か(batch フラグを外す等して)実行してみることをお薦めします。
そして、特に変更の検知がうまく働いているかをチェックしてください。
オプション
Unisonの細かい動作はオプションで設定可能です。
いくつかのオプションはboolean値(しばしばフラグと呼ばれます)をとります。
その他のオプションは数値か文字列を値にとります。
リスト中では数値は n、文字列は xxx と表現します。
文字列をとるオプションのほとんどは複数回設定できます。
設定値はその度に累積されます。
オプションを設定するには2通りの方法があります。
一時的にはコマンドラインオプションとして実行時に指定します。
恒久的には、クライアントの .unison ディレクトリのプロファイルに追記します。
オプション・プロファイルに関わらず、オプションの順番は重要ではありません。
p というオプションをコマンドラインから設定するには、(boolean値の場合)-p、もしくは(数値か文字列の場合)-p n もしくは -p xxx と追加してください。
コマンドラインからboolean値を false にする方法は今のところありません。
しかし、全てのboolean値をとるオプションはデフォルトで false ですので、あなたがプロファイルであるオプションを true にセットしていて、それを一時的に false にしたいという時にだけ、この制限がかかります。
unison -help でオプションの一覧が取得できます。
では、それぞれのオプションについて詳しく見ていきましょう。多くはマニュアルの別のセクションにより深く解説されています。
addprefsto xxx- デフォルトでは、(
ignoreオプション等)Unisonによって加えられる新たなオプションは、Unisonが実行時に読み込むよう指定された設定ファイルに追記されます。addprefsto <filename>を設定することにより、<filename>で設定されたファイルに新たなオプションを追記するようになります。
- デフォルトでは、(
addversionnotrueにセットされた場合、リモートサーバで単にunisonを実行する代わりにunison-<currentversionnumber>を実行します。 これにより一つのサーバマシンにおいてバージョンの異なるUnisonが共存できるようになり、クライアントがどのバージョンのUnisonを使用していても、サーバ側のUnisonのバージョンを選択できることになります。
autotrueにセットされた場合、UIは変更が衝突しない限り、動作について確認を求めなくなります。
backup xxx-backup <pathspec>を含む場合、Unisonは<pathspec>にマッチするpathについてバックアップを作成します。 より詳しく説明すると、<pathspec>にマッチするpathそれぞれについて、更新される際に古い複数のバージョンをバックアップとして残します。 バックアップされたファイルはUNISONBACKUPDIR(デフォルトでは.unison/backup/)で指定されたディレクトリに保存されます。 最新のバックアップは元のファイルと同名で保存され、古いバージョンのファイルは.n.unibckという拡張子をつけて保存されます。 どれだけのバージョンをバックアップするかは、maxbackupsオプションで設定します。
backupstrueにセットされた場合、更新の際に古いバージョンをバックアップとして残すようになります。 バックアップファイルは元のファイルと同じディレクトリに、拡張子.bakを付けた形で保存されます。 ほとんどのユーザにとってbackupフラグよりも有用性は低いでしょう。
batchtrueにセットされた場合、UIはユーザに対して問い合わせを全く行なわなくなります。 更新は衝突しない限り自動的に行なわれ、衝突する更新はスキップします。
contactquietly- フラグが立てられると、起動時にContacting serverというウィンドウ(邪魔に感じるユーザもいるでしょう)を表示しなくなります。
debug xxx- 標準エラー出力に内部の動作内容を出力するようになります。
モジュールの名前と共にデバッグ情報が出力されます。
ソースアーカイブの
Util.debugの中の関数を(grep等を用いて調べて)引数として指定することで、出力される内容をカスタマイズ出来ます。-debug allを指定することで、各モジュールが出力する全てのデバッグ情報を出力させることができます。(Unisonがうまく動かず、内部で何が起こっているのか知りたいときには、これを最初にやってみるべきです。)-debug verboseはいくつかのモジュールからより詳細な情報を得ることができます(ネットワーク越しにどんなバイト列が送信されているかまで見ることができます)。
- 標準エラー出力に内部の動作内容を出力するようになります。
モジュールの名前と共にデバッグ情報が出力されます。
ソースアーカイブの
diff xxx- ファイルの相違点を調べるシステムコマンドの名前と引数を指定することができます。
デフォルトでは
diffです。 指定したプログラムには2つのファイル名を指定して実行されます。
- ファイルの相違点を調べるシステムコマンドの名前と引数を指定することができます。
デフォルトでは
doc xxx-doc <secname>というコマンドラインオプションをつけると、Unisonはマニュアルから<secname>という名前のセクションを探し出して標準出力に表示し、そのまま終了します。 HTMLのマニュアルと同じ内容を含んだマニュアル全体を出力するには-doc allを指定します。-doc topicsを指定すると、指定可能なセクション名を含んだリストが出力されます。
dumbttytrueにセットすると、テキストモードのUIはターミナルのセッティングを変えようとしなくなります(通常Unisonはターミナルをraw modeで使用します。このモードだと、現在表示している行を書き換えるといったようなことができます)。 これは例えばEmacsの中で起動したシェルでUnisonを使うような場合に便利です。dumbttyがセットされると、CUIでコマンドを打ち込んだ後、エンターキーを押す必要があります(通常はユーザがコマンドのキーを打った瞬間にUnisonはコマンドを理解します)。 GUIで起動された場合には、このオプションは影響を与えません。
editor xxx- マージするためのプログラムが
0以外を返した時、その出力を表示するプログラムを指定します。 ユーザがそのファイルを好きなように編集し保存すると、 Unisonはそのバージョンを同期させます。 デフォルトではemacsです。
- マージするためのプログラムが
fastcheck xxxtrueにセットすると、Unisonはファイルの変更をチェックする際、全てのファイルの内容をチェックする代わりにファイルの作成日時を似非inode番号として使います。 Windowsでは、作成日時・変更日時・ファイルサイズが更新で変更されなかった場合、更新に失敗する可能性があります(そうそう起こることではありませんが、起こる可能性はあります)。 しかしUnisonは常に更新を行なう前に安全に変更のチェックを行なっていますので、そのような変更を他のレプリカから上書きしてしまうことはありません。 ですので、Windowsではこのオプションを使うに値するでしょう。 但しそういった変更が見逃されている心配があるのであれば、時々fattcheckをfalseにして実行しましょう。 デフォルトではautoです。 これはUnix上のレプリカに対しては高速なチェックを(Windows上と違い、この場合は安全です)、Windows上のレプリカに対しては遅いチェックを行ないます。 後方互換性の維持のため、yes、no、defaultをtrue、false、autoの代わりに使うことができます。
follow xxx-follow <pathspec>を設定することで、<pathspec>にマッチするシンボリックリンクを透過的に扱い、リンクがある位置にリンクの指し示すオブジェクトがあるかのように振る舞います。
force xxx-force <root>を指定すると、全ての変更を(衝突しない変更に関しても)<root>を基準として解釈します。 これにより、Unisonをミラーリングツールのように動作させることができます。 また-force newer(もしくは-force older)を指定することで新しい(もしくは古い)更新日時のファイルを選択させることができます。 この場合-timeも同時に指定する必要があります。 このオプションは自分が何をしているかわかっている場合に使用すべきです。
grouptrueにセットすると、ファイルのグループ設定も同期されます。 グループの名前やIDはnumericidsオプションに依存します。
height n- GUIでメインウィンドウの高さを(行単位で)指定できます。
ignore xxx-ignore <pathspec>と指定すると、Unisonは<pathspec>にマッチするpathを(再帰的に)無視します。 一時ファイルやオブジェクトファイル等を同期させたくない時に便利です。
ignorecasetrueにセットすると、Windowsのファイル命名規則を使うようになります。 つまり2つのレプリカの間で(大文字・小文字の)綴りの異なるファイルを無視するようになります。 このフラグはWindowsシステムを一つでも含む際には自動的にセットされます。 稀にですが、手動でセットすることも時には有効です(例えばFATパーティションをマウントしたUnixシステムでUnisonを実行するときなど)。
ignorenot xxxignoreオプションを上書きします。絶対に無視すべきでないpathを、ignoreと同じ書式のパターンで渡します。ignoreに指定したパターンと重複していてもいなくても構いません。ignoreとignorenotのセマンティックは直感的に少し解り辛いものがあります。 変更をチェックする際、Unisonはレプリカのrootの浅いところから順に深いところをチェックします。 それぞれのpathをチェックする前に、そのpathがignoreにマッチしてignorenotにマッチしないかを確認します。 そうであればそのpathの全ての子もスキップします。 つまり親がignoreのパターンにマッチした場合、そのpathがignorenotにマッチしていたとしてもスキップされるわけです。 特にignore = Path *とプロファイルに書いて、それからignorenotで同期させたいパターンを指定してもうまく動きません。 代わりに同期させる特定のpathを指定するにはpathオプションを使用すべきです。
key xxx- プロファイルの中で、GUIで素早くプロファイルを切り替えるために(0から9の)数値を指定します。
killservertrueにセットすると、Unisonはファイルの更新が終了した際にリモートのサーバプロセスを終了させます。 この動作はssh接続の場合にはデフォルトですので、ssh接続の際にはこのオプションを設定する必要はありません。 これはソケットモードで起動しているサーバを、一回の更新の後に終了させるために存在します(ずっとサーバを起動しっぱなしではなく、一回の更新ごとにサーバを起動するのを好むユーザもいます)。
label xxx- プロファイルの中で、そのプロファイルを説明する文章を指定します(特にGUIで、複数のプロファイルを切り替えるユーザに有用です)。
log- フラグが立てられると、Unisonはファイルシステムの全ての変更をログに記録します。
logfile xxx- デフォルトではホームディレクトリの
unison.logというファイルにログが追記されていきます。 別のファイルを指定したい場合に設定します。
- デフォルトではホームディレクトリの
maxbackups nbackupでの指定にマッチするpathそれぞれについて、いくつのバージョンまでバックアップをとるかを指定します。 デフォルトでは2です。
merge xxx- 最後のバックアップと両方のレプリカから新しいバージョンのファイルを作成するためのプログラムを指定します。 新しいバージョンのファイルが同期されます。
merge2 xxxmergeに同じ。
numericidstrueにセットされると、グループやユーザは名前ではなく番号で同期されます。 このオプションがセットされていない場合でも、特別なuid 0やgid 0はマップされません。
ownertrueにセットされると、ファイルのオーナー情報も同期されます。 オーナー名やオーナー IDはnumericidsに依存します。
path xxx- 設定されない場合、Unisonは与えられたrootから単純に全てのレプリカを同期させます。
一つ以上の
pathが設定された場合、Unisonはこのpathと子のみを同期させます(例えば一つのディレクトリを素早く同期させたい場合などに有用です)。pathの設定はリテラルに解釈されます。正規表現ではありません。
- 設定されない場合、Unisonは与えられたrootから単純に全てのレプリカを同期させます。
一つ以上の
perms n- どのパーミッションのビットが同期されるべきかを整数で指定します。
デフォルトでは
1777が設定されています。 set-uidビットやset-gidビットの同期はセキュリティ的に問題があるためです。 全てのビットを同期させたい場合は、-1をセットしてください。
- どのパーミッションのビットが同期されるべきかを整数で指定します。
デフォルトでは
prefer xxxforceに同じ。
root xxx- レプリカのrootを指定します。
二つ設定が必要なため、普通はプロファイルに二つ指定するか、プロファイルでは指定せずにコマンドラインで指定することになります。
二つの
rootの指定の順序は関係ありません。 Unisonは動作を起こす前にそれらをソートします。 また同時にホスト名とpathを正確な表記に書き替えます。 それにより、後で異なる名前でrootを指定されても、的確にアーカイブファイルを選択することができるのです。
- レプリカのrootを指定します。
二つ設定が必要なため、普通はプロファイルに二つ指定するか、プロファイルでは指定せずにコマンドラインで指定することになります。
二つの
rootalias xxx- 与えられたrootに対してアーカイブファイルのファイル名を計算する際に、左側に書かれたrootを右側の表記に置き換えます。
rshargs xxx- リモートホストへの接続に使用されるrshやsshに対して、指定された文字列を(ホスト名とリモートホスト上のUnisonの実行可能ファイル名以外を)引数として渡します(このオプションはrshとsshの両方に引数を渡すことができます。それがこのオプションが
sshargsではなくrshargsである理由です)。
- リモートホストへの接続に使用されるrshやsshに対して、指定された文字列を(ホスト名とリモートホスト上のUnisonの実行可能ファイル名以外を)引数として渡します(このオプションはrshとsshの両方に引数を渡すことができます。それがこのオプションが
rshcmd xxx- 必要であれば、rshの実行可能ファイル名を(例えばフルパスで)指定できます。
servercmd xxx- 必要であれば、リモートホスト上のUnisonの実行可能ファイル名を(例えばフルパスで)指定できます。
silenttrueにセットされると、CUIはエラー以外の出力をしなくなります。batchオプションが有効な時には、自動的にsilentもセットされます。
sortbysize- フラグが立てられると、UIは名前ではなくファイルサイズを基準に(小さいものから)ソートしてリスティングします。 例えば回線が遅いために、小さいファイルの転送を大きなファイルで邪魔したくない場合などに便利です。 このオプション(同様に、パターンを引数として取らない他のソートオプション)は、GUIのSortメニューから一時的に選択することもできます。
sortfirst xxx- pathspecを指定します。これにマッチするファイルは優先的にリスティングされます。
sortlast xxxsortfirstと似ていますが、マッチするファイルはリストの後ろに持っていかれます。
sortnewfirst- フラグが立てられると、新たに作成されたファイルを優先的にリスティングします。 例えば新しいファイルがゴミではないか、つまり同期させずに無視したり、削除したりすべきものでないか確認するのに便利です。
sshcmd xxx- 必要であれば、sshの実行可能ファイル名を(例えばフルパスで)指定できます。
sshversion xxx- サーバとの接続に用いるsshのプロトコルを指定します。
1もしくは2を指定することで、ssh1もしくはssh2を用いてサーバへ接続を試みます。 デフォルトは空です。 Unisonはsshとしてインストールされているコマンドを用います。
- サーバとの接続に用いるsshのプロトコルを指定します。
statusdepth n- 指定された数より深いローカルのディレクトリについて、変更を調べる際の出力を抑制します。(ローカルの状況をあまりたくさん表示すると、変更の検知をいくらか遅くします。)
tersetrueにセットされると、UIはステータスを表示しなくなります。
testserver- リモートサーバに接続を試み、成功すればメッセージを表示してすぐに終了します。 インストール時のトラブルシューティングに有効です。プロファイルに書くべきではありません。
times- ファイルの更新日時(ディレクトリは対象外です)も同期させます。
ui xxx- GUIかCUIを選ぶために、
graphicもしくはtextを指定します。 CUIのみに対応したバイナリでは、このオプションは影響を与えません。
- GUIかCUIを選ぶために、
version- バージョン番号を出力して終了します。 コマンドラインでのみ意味を持ちます。
xferbycopying- 対象のレプリカに同じ内容のファイルがあるかを検知して、ファイルがあった場合、その内容をネットワークに流さないよう試みます。
移動されたファイルの更新が素早く済むようになります。
デフォルトでは
trueです。
- 対象のレプリカに同じ内容のファイルがあるかを検知して、ファイルがあった場合、その内容をネットワークに流さないよう試みます。
移動されたファイルの更新が素早く済むようになります。
デフォルトでは
プロファイル
プロファイルとは root や path、ignore 等の設定を記述したテキストファイルです。
これを用意することで、実行する際にいちいちコマンドラインでオプションを打つ必要がなくなります。
プロファイルはクライアントマシンの .unison ディレクトリに置いておく必要があります。
Unisonが name という一つの引数だけで実行された場合、.unison ディレクトリの name.prf というファイルをプロファイルを読み込みます。
引数無しで実行された場合、(GUIでは).unison ディレクトリの .prf というファイルを全て探し出し、選択可能なメニューを表示します。
default.prf というファイルがある場合には、その設定がデフォルトで選択されます。
p というオプションを設定する場合、boolean値を取るオプションはプロファイルに
p = true
のように記述します。 他のタイプの値を取るオプションは
p = <value>
というように記述します。
p と xxx の周りの空白は無視されます。
空行を含んでいても構いません。
また # で始まる行も空行と共に無視されます。
Unisonを実行すると、まずプロファイルを読んでからコマンドラインオプションを読みますので、プロファイルでの設定をコマンドラインオプションで上書きすることができます。
プロファイルには include name という行を含めることができます。
これにより name というファイル(もしくは .unison ディレクトリに name というファイルがなければ name.prf というファイル)の内容がinclude行の位置に記述されていると見なされます。
include行により、複数のプロファイルに共通の設定を一つのファイルにまとめておくことができます。
プロファイルには label = desc という行を含めることができます。
desc にはそのプロファイルの説明を書いておきます。
GUIで実行する際、プロファイル選択ダイアログでプロファイルと共に desc の内容が表示され、実行中のメインウィンドウの右上にも同様に desc の内容が表示されます。
GUIではまた、よく使うプロファイルにショートカットを登録しておくこともできます。
プロファイルに key = n(n は一桁の整数)という行が含まれる場合、その数字のキーを叩くことで即座にプロファイルを切り替え、同期を開始することができます。
この場合、現在表示され選択されている内容は破棄されます。
プロファイルのサンプル
最小限のプロファイル
最小限のプロファイルのサンプルです。
root = /home/bcpierce
root = ssh://saul//home/bcpierce
path = current
path = common
path = .netscape/bookmarks.html
基本的なプロファイル
有用なオプションを含んだ、もう少し洗練されたサンプルです。
root = /home/bcpierce
root = ssh://saul//home/bcpierce
path = current
path = common
path = .netscape/bookmarks.html
ignore = Name temp.*
ignore = Name *~
ignore = Name .*~
ignore = Path */pilot/backup/Archive_*
ignore = Name *.o
ignore = Name *.tmp
height = 37
backup = Name *
diff = diff -y -W 79 --suppress-common-lines
log = true
パワーユーザ向けプロファイル
Unisonが巨大なレプリカに対して実行される時、しばしばレプリカの一部分のみを同期の対象として指定する方が(他の箇所の変更を調べる時間を節約できる分)便利です。 これはプロファイルをいくつかのパートに分けることで実現できます。 具体的には、基本的な設定を含んだパートと、同期させたいそれぞれのpathについてのトップレベルのパートです(include機能も同様に異なるrootに対して共通の設定を提供する目的で利用できます)。
この構想を実現するプロファイルは以下のようになります。
default.prf というファイルにはinclude行のみを含めます。
include common
共通のファイルの名前は common.prf ではなく common にしてください。
これにより、UnisonがGUIでプロファイルの選択肢に common を含むことを防ぎます。
common には実際の設定を書きます。
addprefsto = common
ignore = Name temp.*
ignore = Name *~
ignore = Name .*~
ignore = Path */pilot/backup/Archive_*
ignore = Name *.o
ignore = Name *.tmp
common にはpathの設定を書きません。
つまり、デフォルトのプロファイルでUnisonを実行した場合(つまり unison default もしくは単に unison のみで実行した場合)、レプリカ全体が同期されるということです(レプリカ全体を絶対に同期させたくない場合には、default.prf に同期させるpathを設定すべきです)。
レプリカの一部のpathのみを同期させるために、(例えば unison papers のように)別のプロファイルを指定して実行します。
papers.prf には以下のように記述します。
path = current/papers
path = older/papers
include common
これにより、Unisonは current/papers と older/papers のみを同期するようになります。
GUIで異なるpathの設定に素早く切り替えるために、key オプションが指定できます。
例えば、mail.prf には以下のように記述します。
path = Mail
batch = true
key = 2
include common
これにより、2を叩くだけで Mail というサブディレクトリのみを見るようになり、(batch フラグが立っているために)すぐに更新が実行されます。
バックアップをとる
更新を行なう際に、古いバージョンのファイルのバックアップを取ることができます。 この機能により、一般的なバックアップを行なうと同時に、外部のマージするためのプログラムを実行する際に一般的なバージョンを提供することもできます。
バックアップされたファイルは双方のホストの ~/.unison/backup ディレクトリに保存されます。
このディレクトリは UNISONBACKUPDIR という環境変数に値を設定することで変更することもできます。
Unisonがアーカイブを更新する際にファイルはバックアップディレクトリへと保存されます。
つまり
- Unisonがアーカイブをスクラッチから再構築する際(例えばアップグレードや、アーカイブファイルが手動で削除された時等)に、全てのファイルがバックアップされます。
- もしくは、Unisonがあるファイルについて更新作業を行なった際、そのファイルはバックアップされます。
バックアップファイルを手動で削除(もしくはバックアップディレクトリごと削除)しても安全です。 Unisonはこれらのファイルを重要なことに使う前に、期待するファイルとフィンガープリントが一致することを確認します。
backup オプションはどのファイルが実際にバックアップされるかを設定します。
例えば、backup = Path * という指定をすると、全てのファイルがバックアップされます。
backupversions オプションは、いくつのバージョンまでがバックアップされるかを設定します。
デフォルトでは 2 です(つまり最後に同期されたバージョンともう一つ古いバージョンがバックアップされます)。
後方互換性のため backups オプションはいまだサポートされていますが、現在では backup を使うようにしてください。
更新をマージする
CUI・GUIの両方のUIは、インタラクティブに衝突をマージする merge コマンドを提供します。
これは衝突しているファイルを選択してmを叩くことで実行できます。
実際のマージ作業は、外部プログラムにより行なわれます。
merge オプションと merge2 オプションが、どのように外部プログラムが起動されるかを指定しています。
このファイルのバックアップファイルが存在する場合、merge オプションが使用されます。
そうでなければ merge2 オプションが使用されます。
いずれの場合も、オプションには外部プログラムを実行するためにシェルに渡されるコマンド名を指定します。
この文字列には CURRENT1、CURRENT2、NEW、そして OLD という特別な文字列を含めます。
Unisonはこれらの文字列を、コマンドの実行前に以下のように置き換えます。
CURRENT1はファイルのローカルコピーの名前に置き換えられます。CURRENT2は前もってリモートからコピーされたファイルの内容を含む一時ファイルの名前に置き換えられます。NEWはマージ作業後に保存されるべきファイル名と置き換えられます。OLDはそのファイルの元のバージョンのバックアップ(例えば最後の更新が成功した際の状態)があれば、そのファイル名と置き換えられます。OLDの置き換えはmergeのみによってなされます。merge2では行なわれません。
例えば、Unixシステムで merge オプションを
merge = diff3 -m CURRENT1 OLD CURRENT2 > NEW
のように指定すると、Unisonはマージに diff3 というコマンドを使います。
外部のマージプログラムを複数指定することもできます。
例えば、Emacsユーザは以下のような設定が気に入るでしょう。
merge2 = emacs -q --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")'
merge = emacs -q --eval '(ediff-merge-files-with-ancestor "CURRENT1" "CURRENT2" "OLD" nil "NEW")'
外部プログラムが NEW に対応するファイルを保存せずに終了した場合、Unisonはマージが失敗したと判断します。
マージプログラムが NEW というファイルを保存したが、終了コードが 0 以外の値を返した場合、マージは成功したが、同時に衝突も発生したと判断します。
この場合、外部のエディタを起動してユーザが衝突を解決できるようにします。
editor オプションはUnisonによって起動されるエディタを指定します。
デフォルトではEmacsです。
merge2 や merge の便利な設定を是非教えてください。マニュアルにもう少し例を載せたいのです。
ユーザインタフェース
CUIもGUIも、それ自身が一目瞭然に作られています。 少しだけトリックを紹介しておきます。
- デフォルトでは、UnisonをUnix上で実行するとターミナルを raw mode に変更しようとします。
これにより、キーを叩いた瞬間に(エンターを押さなくても)Unisonはコマンドを解釈できるのです(つまりUnisonに左から右に更新するという指示を出す際に、> Enterではなく> を叩くだけで済むということです)。
しかしこの機能うまく働かないこともあります。
例えばEmacsの中でシェルを立ち上げてUnisonを使うような場合です。
dumbttyオプションを設定するとUnisonはターミナルの状態を変更せず、入力を一行ごとに解釈するようになります。
終了コード
テキストモードで実行する際、Unisonは終了コードを返します。 終了コードは同期が成功したかしなかったか、もしくはどこまで成功したのかを示します。 スクリプトからUnisonを利用する際に便利です。 Unisonが返し得る終了コードは4種類あります。
- 0: 同期成功。全てのファイルは最新である。
- 1: いくつかのファイルをスキップしたが、全ての転送は成功した。
- 2: 転送の最中に致命的でないエラーが発生した。
- 3: 致命的なエラーが発生し、実行が停止した。
GUIでは有用な終了コードを返しません。
pathの仕様
いくつかのUnisonのオプション(ignore/ignorenot、follow、sortfirst/sortlast、backup)にはある一つpathやpathのセットを指定する必要があります。
これらのオプションは正規表現をベースとしたシンタックスを共有しています。
それぞれのオプションのpathパターンのリストと関係しています。
特定のpathはpathパターンの一つにマッチします。
- パターンオプションはコマンドラインやプロファイルの中で、他のオプションと同様の書式で指定できます。
例えばプロファイルに
ignore = patternと記述すると、無視されるべきpathのリストにpatternを加えることができます。 patternはそれぞれ三つのうち一つの形式で記述することができます。 最も一般的なのは、POSIXの拡張正規表現の形式であるRegex(Regex regexp)です(照合順序や文字クラス等のPOSIXの全ての正規表現は今のところサポートされていません)。 利便性のため、もう2つの形式も理解できます。Name nameは最後の要素がnameであるpathにマッチします。Path pathは正確にpathにマッチするpathを指します。 後者のnameとpathという引数は正規表現ではありません。 代わりに、標準的なグロビングが使用できます。?は/以外の任意の1文字にマッチします。*は/以外の任意の文字列にマッチします。[xyz]はx,y,zのいずれかの文字にマッチします。{a,bb,ccc}はaかbb、もしくはcccにマッチします。
- pathの区切り文字は常に
/です。 クライアントやサーバがWindows(デフォルトの区切りが\)で動作していても同様です。 これによりWindowsでもUnixでも同じpathのパターンが利用可能なのです。
pathを無視する
Unisonのユーザは、一時ファイルや巨大なファイル、古いファイル、アーキテクチャに依存したバイナリファイル等、同期させたくないファイルがレプリカに多く含まれていることに気付くでしょう。
これらのファイルを同期させないよう、ignore オプションで無視すべきpathを指定することが出来ます。
例えば、以下のように指定することで CVS や .cmo というファイルを同期させないよう設定することができます。
ignore = Name {CVS,*.cmo}
次のパターンは a/b というpathを無視させることができます。
ignore = Path a/b
このパターンは a/b で始まり .ml で終わるpathを無視させることができます。
ignore = Regex a/b/.*\.ml
正規表現によるpathの指定は固定されることに注意してください。 つまりpathの一部だけではなく、pathの全体がマッチする必要があります。
ignore オプションには他にもいくつかのポイントがあります。
- あるディレクトリが無視されると、そのサブディレクトリも無視されます。
ignoreパターンを追加するのに便利なコマンドをUIは提供します。 特定のファイルを無視したい場合は、そのファイルを選択してiを叩いてください。 同じ拡張子の全てのファイルを無視したい場合はEを叩いてください。 ディレクトリに関係なく同じ名前の全てのファイルを無視したい場合はNを叩いてください。 新しいパターンはすぐにディスク上の現在のプロファイルに追加されます。- プロファイルで
include設定を使っている場合は、addprefsto設定も使うべきでしょう。 この設定を行なうと、UIから新たに追加したignore設定を、トップレベルの設定ではなく、どのファイルに追記すべきかを指定できます。 - あまり便利とは言えませんが、
ignoreパターンはコマンドラインでも指定できます。-ignore "Name temp.txt"等のように指定してください。
シンボリックリンク
通常UnisonはUnixのレプリカの中のシンボリックリンクを非透過的に扱います。 つまりシンボリックリンクを、そのリンクが指し示す先を表わす文字列として扱い、その文字列を他のレプリカに更新します。
シンボリックリンクを、リンクがある場所に実際にファイルがあるかのように、つまり透過的に扱うことはしばしば有用です。 Unisonにシンボリックリンクをこのように扱うように指示するには、プロファイルに
follow = pathspec
というように追記します。
pathspec はpathパターンを表わします。
Windowsのファイルシステムはシンボリックリンクをサポートしていません。
UnisonはUnix上のシンボリックリンクをWindows上に非透過的に転送することができません。
そのpathはエラーがあるとしてフラグが立てられます。
Unix上のレプリカがWindows上のレプリカと同期される場合、全てのシンボリックリンクは ignore パターンか follow パターンのいずれかにマッチする必要があります。
パーミッション
二つの異なるファイルシステムの間(例えばWindowsのクライアントとUnixのサーバの間)でパーミッションのビットを同期させるのは些かトリッキーです。 以下に、その仕組みがどのようにして動作しているかを示します。
- 存在するファイルやディレクトリのパーミッションが変更された場合、パーミッションが両方のシステムに理解される場合には、パーミッションも同期されます。 そうでなければパーミッションはそのまま保存されます。
- 新規に作成されたファイルがリモートのレプリカに転送される際、両方のシステムに理解されるパーミッションはそのまま同期されます。 それ以外のパーミッションのビットはデフォルトの値にセットされます(Unixシステムでは現在のumaskの値が用いられます)。
- セキュリティの観点から、Unixのsetuidとsetgidビットは同期されません。
- UnixのオーナーとグループのIDは同期されません(これは一般に何を意味しますか?)。 全てのファイルはサーバプロセスのオーナーとグループによって作成されます。
クロスプラットホームでの同期
WindowsとUnixの間でUnisonでファイルを同期させる場合、知っているべき問題がいくつかあります。
大文字・小文字の問題: Unixではファイル名の大文字と小文字は区別されます。
foo と FOO は異なるファイルを指します。
一方Windowsでは大文字と小文字の違いは無視されます。
foo と FOO は同じファイルを指します。
つまりこれはUnix上の foo と FOO というファイルは、Windowsに転送できないということを意味します。
Windowsは同じ名前で異なるファイルの存在を許さないからです。
Unisonはこの問題を探知し、ファイルを同期できない旨を報告します。
ファイル名の大文字・小文字の問題を解決する方法はあります。
Windowsに両方のファイルを転送する必要がある場合、唯一の方法はUnix上で一つのファイル名を変更し、再度同期させることです。
Windowsにファイルを転送する必要がない場合は、単純にUnisonの警告を無視し、同期させる作業を続けてください。
Unisonはそれらのファイルには触れません。
同期させる度に警告を表示させるのが嫌ならば、ignore オプションを設定して無視させてください。
無効なファイル名: Unixでは有効なファイル名がWindowsでは無効なことがあります。
例えばコロン(:)はWindowsではファイル名として使えませんが、 Unixでは使うことができます。
これはUnix上の foo:bar というファイルがWindowsに転送できないことを意味します。
大文字・小文字の場合と同様、Unisonはその状況を探知し、報告します。
回避するのも同様に、Unixでファイル名を変えて再度同期させるか、単純に無視しましょう。
狭い帯域幅
Unisonは比較的遅いダイアルアップやDSLの回線でも十分に動作するように作られています。
UnisonはAndrew TridgellとPaul Mackerrasによってデザインされた、小さな変更を加えられた巨大なファイルの転送を最適化するrsyncプロトコルを利用しています。 rsyncプロトコルについてはrsyncのWebサイトを参照してください。
Unisonをssh越しに利用している場合、sshの圧縮機能を利用して転送速度を多少向上させることができます。
これにはコマンドラインで -rshargs -C と指定するか、プロファイルに rshargs = -C と追加します。
高速な変更検知
レプリカが巨大で且つどちらかが(もしくは両方が)Windowsシステムである場合、Unisonのデフォルトの変更検知プロセスが遅すぎると感じるかもしれません。
Unisonには fastcheck オプションがあります。
yes にセットすると、Unisonはファイルの変更をチェックする際、全てのファイルの内容をチェックする代わりにファイルの作成日時を似非inode番号として使うことで、変更をより速く検知することができます。
この方法を使うと、Windowsでは、作成日時・変更日時・ファイルサイズが更新で変更されなかった場合、更新に失敗する可能性があります。
しかしUnisonは常に更新を行なう前に安全に変更のチェックを行なっていますので、そのような変更を他のレプリカから上書きしてしまうことはありません。
ですので、Windowsではこのオプションを使うに値するでしょう。
但しそういった変更が見逃されている心配があるのであれば、時々 fattcheck を false にして実行しましょう。
クリックで起動
Windows NTや2000のシステムでは、GUIバージョンのUnisonを直接クリックすることで起動することも可能です。 Windows 95や98では、sshを使わない限りはクリックして起動することもできます。 OCamlとWindows 95/98との相性問題は解決できていないので、sshを使いたい場合はDOSプロンプトから起動する必要があります。
Unisonのアイコンをクリックすると、2つのウィンドウが表示されます。 Unisonの通常のウィンドウと、sshのパスワードを入力するためだけのコンソールウィンドウです(sshを使わないのであれば無視して構いません)。 パスワードの入力が促されたら、入力する前にコンソールウィンドウに(クリックするなどして)フォーカスを当てる必要があります。 DOSプロンプトからUnisonを起動した場合は、パスワードはDOSプロンプトに入力してください。
このモードでUnisonを利用するには、前もってプロファイルを作っておく必要があります。 好きなエディタを使って作成してください。
仕様
Unisonはシンプルな仕様に基づいています。
root
レプリカの root とは、ローカルマシン及びリモートマシンにおいて、同期を取るべきファイル群の場所を表わします。 例えば
relative/path/of/root
はローカルマシンにおけるrootを、Unisonが実行されたディレクトリからの相対パスとして表わし、
/absolute/path/of/root
はどこでUnisonが実行されたかは関係無く、ローカルマシンのファイルシステムにおける絶対パスでrootを示しています。
リモートホストのrootは、接続に用いるプロトコルによって ssh://、もしくは rsh:// を先頭に付け加えます。
ssh://remotehost//absolute/path/of/root
rsh://user@remotehost/relative/path/of/root
リモートホストでUnisonサーバが動いているのであれば、
socket://remotehost:portnum//absolute/path/of/root
socket://remotehost:portnum/relative/path/of/root
このように書くことで、クライアントのUnisonが接続すべきリモートホストとポート番号を明示します。
rootの書式はURI(RFC 2396)の書式に基づきます。
pathにプロトコルを示すプレフィクスが付いていない場合、プロトコルは file: であると見なされます。
Windowsの場合、ファイル共有機能と file: プロトコルを用いてファイルの同期を取ることが出来ます。
unison foo //host/drive/bar
というように実行すると、ローカルの foo というディレクトリと、host というマシンの drive:\bar の同期を取ります(但しこの方法は、ホスト間が十分に速い回線で接続されている場合に限った方が良いでしょう。更新を検知するために、リモートマシンのレプリカがローカルマシンに転送される必要があるからです)。
rootの名前は実行時にUnisonによって内部的に変換されます。
各rootに対応するアーカイブファイル名を特定するためです。
つまり //saul//home/bcpierce/common と //saul.cis.upenn.edu/common は名前の違う同一のレプリカであると認識されます。
path
pathとは同期を取るファイル群の中の一つを指します。 レプリカのrootからの相対パスで表わされます。
pathは単なる / で区切られた名前の羅列です。
Unisonが動作する環境に関係無く、pathの区切りは常に /(スラッシュ)であることに注意してください。
ローカルのファイルシステムにおいて必要がある場合は、/ は \(バックスラッシュ)に自動的に変換されます(例えばWindowsマシンの c:\pierce とUnixサーバの ssh://saul.cis.upenn.edu/home/bcpierce の同期を取る場合、current/todo.txt というpathはクライアントでは c:\pierce\current\todo.txt となり、サーバでは /home/bcpierce/current/todo.txt となります)。
pathが空の場合、レプリカ全体を表わします。
Unisonは空のpathを [root] と表示します。
変更
あるレプリカのpath、p の指し示す内容は、ファイルかディレクトリ、シンボリックリンク、もしくは(p がレプリカの中の何も指し示していない時は)空っぽであるかもしれません。
より詳しく見てみましょう。
pが普通のファイルを指す場合、pはこのファイルの実際の内容(つまりバイト列)と、パーミッションを表わすビット列です。pがシンボリックリンクを指す場合、pはシンボリックリンクが指し示している先の内容です。pがディレクトリを指す場合、pは単なる "DIRECTORY" というトークンと、パーミッションを表わすビット列です。pがレプリカの中の何も指していない場合、pは "ABSENT" というトークンになります。
Unisonは同期が成功した後、それぞれのpathの内容を記憶します(つまり2つのレプリカの内容が同じであったときの最後の状態を記憶しているわけです)。
あるレプリカにおいて、pathの中身が最後に同期させた時から見て変更されている場合、そのpathは変更されたと判断します。
衝突
以下のような場合、そのpathは衝突しているとされます。
- どちらかのレプリカで変更された。
- そのpathかその子がもう一方のレプリカで変更された。そして
- 2つのレプリカの同一のpathの内容が異なる。
衝突の解決
Unisonはいくつかの異なった段階を踏みます。
- それぞれのホストにおいて、どのpathが変更されたか判断するために、現在のレプリカの内容とアーカイブファイルの内容を比較します。
- 両方のレプリカで変更されていて、なおかつ内容が異なるpath(false conflicts)を調べます。 これらのpathは両方のレプリカにおいて、同期されたと内部的にマークされます。
- 更新されたpathをユーザに提示します。 衝突しない更新に関しては、更新されたレプリカ同様にもう一方を更新するという、デフォルトの動作を提案します。 衝突する更新は単に表示されます。 ユーザはレプリカ全体の更新状況を見極め、衝突しない更新の動作を変え、衝突する更新に対する動作を決めることができます。
- 選択された動作を一つずつ実行します。 転送されたファイルはまず受け取り側のホストに一時ファイルとして作成され、次にそのファイルをあるべき場所に移動します。
- アーカイブファイルに現在のレプリカの内容を反映します。
原則
その実行内容の重要性と繊細さから、シンクロナイザが通常の状態でどのような動作をしているのかだけでなく、システムのクラッシュや通信が切断した場合等の異常事態にどのように動作するのかを知ることもまた重要です。
Unisonは実行中、常に内部の状態やレプリカの状態を保護するよう設計されています。 特に、以下のような特徴を備えています。
- 双方のレプリカの全てのpathは、1)その元の状態(つまり変更されていない状態)か、2)その正常に更新された状態(つまりユーザが意図した内容に更新された状態)のいずれかを常に保持しています。
- ディスク上に保存されたUnison内部の情報は常に、1)変更されていない状態か、2)同期に成功したpathの情報を反映した状態のいずれかです。
つまり結論として、人為的にであろうと事故であろうと、いつUnisonの実行を停止しても安全だということが言えます。
更新を実行している最中に停止された場合、あるpathの更新は完了しているのにアーカイブファイルにその更新が反映されていないということが起こり得ます。 しかし問題はありません。 次にUnisonが実行された際に、Unisonはこれらのpathが変更されていながらも内容は同じであると判断し、同期は成功したと記憶してそのpathに関する処理を終了するからです。
Unisonが停止された場合、レプリカの中に(.tmp という拡張子の付いた)一時ファイルが残っていることがあります。
それらのファイルは消してしまって構いません。
同様に(deprecatedな)backupフラグが設定されている場合、Unisonは file.0.unison.bak というような古いバージョンのファイルを残します。
これらのファイルも、Unisonの動作には影響ありませんから、消してしまって結構です。
Unisonは、動作しているマシンの間のクロック・スキュー(クロックのばらつき)には影響されません。 Unisonは単に一つのホスト上で手に入れたタイムスタンプの比較を行ない、それを行なう上で必要な前提は、それぞれのシステムのクロックが常に前に進むということだけだからです。
アーカイブファイルが削除されている(もしくはファイルのフォーマットが変更されていて読み込めない、もしくはあるrootに対して初めて実行したためまだファイルが作られていない)場合、Unisonは非常に保守的な動作をします。 つまり双方のレプリカが最後の更新時に完全に空であったかのように動作します。 その結果、初めての実行時には一方のレプリカに存在するファイルは他方に転送され、両方のレプリカに存在しながら内容が異なるファイルは衝突しているとマークされます。
あるファイルに対して変更を加えずに更新時刻だけを変更する(touchする)操作は、Unisonの動作に影響を与えません。 Unixでは、Unisonはどのファイルが絶対に更新されていないかを知るために、まずファイルの更新時刻を調べます。 そして更新された可能性のあるファイルに対してフィンガープリントを計算し、最後の更新時の状態と比較します。
アーカイブファイルを両方のレプリカから削除して、Unisonを洗脳しても構いません。 次に実行した時、Unisonはレプリカの全てのファイルが新しく作られたものだと仮定します。
Unisonの実行の最中にファイルに変更を加えても安全です。 古い状態で更新してしまった時、もしくは更新している最中にターゲットのレプリカのファイルが変更された時は、Unisonはそのファイルの更新に失敗した旨を表示します。 最新の更新を行なうにはもう一度Unisonを実行してください。
UIからの(例えば i キー等による)無視(ignore)パターンの変更は、すぐに現在のプロファイルに反映されます。
警告と短所
Unisonを利用する際に注意すべきことがあります。
バグの完全なリストは、ソースアーカイブの中の BUGS.txt にあります。
- 高速化のため、(実行するOSのアーキテクチャにもよりますが)変更検知アルゴリズムは実際には近似的な方法を用いることがあります。
- 特にUnixにおける実装では、ファイルの実際の内容と前回の記録とを比べるのではなく、ファイルのinode番号と更新時刻のみをチェックしています。 どちらも変更されていなければ、そのファイルは変更されていないという結論に達します。
- 一般的な状況では、この方法は変更を見誤ることがあっても、本当の更新を見逃さないという点で安全です。 しかし、retouch等を使ってファイルの更新時刻を巻き戻し、Unisonを騙すことは可能です。
- 自分専用のファイルシステムと共有のサーバの間でファイルを同期させる場合、パーミッションに気をつける必要があります。
Unisonはデフォルトではパーミッションもそのまま同期させるので、グループに書き込み権限を残したまま同期させてしまうと、他のユーザに上書きされてしまう可能性があります。
- 両方のマシンでumaskを022などに設定してこの問題を回避することができます。
- GUIは今のところシングルスレッドで動いています。 これはUnisonが時間の掛かる処理を行なっている時、その処理が終了するまで画面が書き換わらないということを意味します。 Unisonが何らかの動作している間、GUI画面に触らないようにすることをお薦めします。
- Unisonは今のところハードリンクを理解しません。
アドバイス
FAQ
Unisonとrsyncの違いは何ですか?
端的に言ってしまえば、rsyncはミラーリングツールで、Unisonはシンクロナイザです。 つまりrsyncには「このレプリカが最新バージョンですから、もう一方をこれで上書きしてください」と指示する必要があるのですが、Unisonはレプリカをそれぞれ見比べて、どちらでもう一方を上書きすべきか勝手に判断してくれます。
Unisonもrsyncも、更新にはAndrew TridgellとPaul Mackerrasによるrsyncアルゴリズムを用いています。 これは巨大なファイルの一部分のみが変更された場合に、転送効率を最適化するアルゴリズムです。
UnisonとCVSの違いは何ですか?
(訳注: まずはファイルシンクロナイザであるUnisonとリビジョン管理システムであるCVSの本質的な違いを押さえておくべきでしょう。)
両方とも、中心となるリポジトリの内容に応じて、ディレクトリ構造からなるリモートのレプリカを最新に保つことができます。 また双方向にファイルの更新を行なったり、衝突する更新を検知したりもできます。 同時に、UnisonもCVSもファイルの転送にはrsyncのものと同じプロトコルを用います。
CVSに勝るUnisonの利点は、特に大量のファイルに対して、より自動的に、簡単に更新が行なえることでしょう。 CVSを使う場合は、ファイルを追加したり削除したりした場合に、手動でその手続きを行なう必要があります。 ファイルを移動する場合は少しトリッキーです。 ディレクトリを移動したい場合なんか‥‥まあ、これは実際にやってみてください。
しかしながら成熟したリビジョンコントロールシステムであるCVSは、例えば履歴や複数のブランチを保持できる等、単なるファイルシンクロナイザであるUnisonにはない多くの機能を備えています。
NFSでリモートのファイルシステムをマウントしてローカルでUnisonを実行しても構いませんか?それともリモートでサーバを起動しておく必要がありますか?
ローカルネットワークが十分に速いのであれば、レプリカをNFSでマウントしても構いません。 Unisonは(特に同期の度に全てのファイルの更新時刻をチェックする必要があるために)たくさんのファイルを読む必要があります。 よって帯域が細いのであれば、リモートでサーバを起動しておいた方が良いでしょう。
WindowsでGUIを起動すると、メインのウィンドウと空のコンソールウィンドウが開きます。コンソールウィンドウを開かなくすることはできますか?
コンソールウィンドウはsshのパスワードを入力する時に使います。 残念ながら現在のバージョンのUnisonでは、sshを利用するか否かに関わらず、コンソールウィンドウが表示されてしまいます。
Karl Moerderがコンソールウィンドウの見た目をもう少し良くするためのスクリプトを公開しています。 彼の方法では、.cmdファイルへのショートカットからUnisonを起動します。 するとコンソールウィンドウのサイズを小さくし、背景を灰色にし、パスフレーズの入力欄をセンタリングさせる等、ウィンドウの属性をコントロールすることができるようになります。 彼の書いたスクリプトはhttp://www.cis.upenn.edu/~bcpierce/unison/download/resources/karls-winhax.zipからダウンロードできます。
また(ソケットモードでサーバに接続しているユーザは)アイコンに細工することでウィンドウを消してしまうこともできます。 実行可能ファイルに対してショートカットを設定しているなら、プロパティを設定してそのウィンドウが最小化された状態で表示することができます(最小化ですから、タスクバーからも消してしまうことはできませんが)。
推移的に用いた場合でもUnisonはうまく動きますか?つまり host1/dir と host2/dir、host2/dir と host3/dir をそれぞれ違うタイミングで同期させても大丈夫ですか?接続のグラフがループになっていると何か問題になりますか?
大丈夫でしょう。 それぞれのホストのペアが接続されている限り、Unisonが他のホストとの間で行なった更新がファイルシステムに及ぼす影響は、ユーザが手動で行なった場合と変わりませんから。 もし一つのホスト上のみで変更されたファイルがあり、Unisonがそのファイルが変更されたことを発見した場合には、もう一方のホストで変更されていなければそのファイルがもう一方のホストに転送されます。 もし両方のホストで変更されていると確認した場合は、そのファイルには手をつけません。 よって接続のグラフがループになっているように見えても、(接続が分かれていない限りは)全てのホストでファイルが最新のものに更新されます。
この場合気をつけるべきことがあるとすれば、最初のマシン(むしろ実際は他の全てのマシンについてなのですが)に対して、全てのマシンがファイルの変更を知る前にもう一度更新をかけてしまわないことです。 この場合Unisonはファイルが衝突したと判断するため、手作業で衝突を解決しなければなりません。
/dev や /proc のファイルのように特別なファイルを同期させようとするとどうなりますか?
Unisonは単純に同期を拒否します。 Unisonは一般ファイル、ディレクトリ、シンボリックリンクのみを扱えます。
Unisonを同時に複数実行することはできますか?
Unisonはこのような状況に対応しています。 が、あまりテストされてはいませんので、実行する際には注意してください。
ローカル(もしくはNFS等)でUnisonを実行した際、もしあるファイルが両方のレプリカに含まれていた場合はどうなりますか?
同期させようとしていたファイルが他の誰かによって変更されたと判断し、それらのファイルについて(安全に)同期を失敗します。
Unisonが実行中にkillされたらどうなりますか?普通にkillすべきか、もしくはkill -9すべきでしょうか。同期の最中にネットワークが切れたらどうなりますか?一方のマシンがクラッシュしてもう一方が動きつづけた場合は?
心配には及びません。
Unisonと他のプログラム、もしくはユーザが同じファイルにちょうど同時に書き込もうとするような状況ではどうですか?
そういった windows of danger はできるだけ短時間に済ますように努力しますが、その危険性は完全には消し去れません。
UnixのファイルロックはNFS上ではうまく機能しませんが、Unisonにとって問題となりますか?
いいえ。
Windowsシステムで、root オプションはバックスラッシュで区切られているように見えますが、path オプションや ignore オプションはスラッシュで区切られています。どういうことですか?
Unisonは2種類のpathを使います。
ローカルファイルシステムのシンタックスを用いたネイティブのファイルシステムのpathと、常にスラッシュを区切り文字に用いるポータブルな pathです。
root オプションはネイティブのpath、その他はrootから相対的に表現されます。
一般的な問題
Unisonを使っていて問題が発生した時には、以下の情報が解決の助けになるかもしれません。
まず一般的な推奨事項として、理解し難い状況に陥った時はアーカイブファイル(.unison ディレクトリに arNNNNNNNNNNNNNNN のような名前で保存されています)を削除することで、最初の状態に戻すことができます。
2つのレプリカが同一である場合には、アーカイブファイルを削除しても問題ありません。
もし変更点がある場合には、変更されたファイルがもう一方のレプリカにコピーされ、両方のレプリカに同名の、しかし内容の異なるファイルがある場合には衝突として報告されます。
もしUnisonが明らかにバグであるというような動作をした場合には、アーカイブを一旦別の場所に移動してしまうのも手です。 そうすることでその動作を再現することができ、より詳細にバグの報告ができます。
CUIでssh2越しに使った場合にUncaught exception Sys_blocked_ioというエラーが出ます。
これはssh2がその標準出力を non-blocked で開くことが原因です。 しかしUnisonとsshは標準エラー出力とnon-blockedな設定を共有しています(ですからサーバから送られてきたエラーが表示されるのです)。 これはUnisonの実行時に
unison -ui text < other args > 2>/dev/tty
として標準エラー出力をリダイレクトすることで解決できます。
但しこのリダイレクトの書式はシェルによって少し異なります。 例えばcshやtcshを使っている場合には
unison -ui text < other args > >&/dev/tty
とする必要があります。
以下のようなエラーはどんな意味ですか?
Propagating updates [accounting/fedscwh3qt2000.wb3]
failed: error in renaming locally:
/DANGER.README: permission denied
これはUnisonが、中止されるとファイルシステムを良くない状態にするような動作を行なう時にコミットログとして用いる(accounting/fedscwh3qt2000.wb3 という実際の場所に対して accounting/fedscwh3qt2000.wb3.unison.tmp という名前で残っている一時ファイルと同様のものです)DANGER.README というファイルを作成する際にエラーが発生したことを示します。
リネームの操作は短時間に行なわれますが、しかしながら可能性はあります。
もしこの状況が発生した場合コミットログはそのまま残され、次回実行された際にファイルの一貫性がチェックされるべきであることをUnisonに教えます(同時にユーザにも報告されます)。
ここではホームディレクトリ(/ に設定されているのでしょう)に DANGER.README というファイルを作成しようとしたが、書き込み権限がなかったことを意味しています。
コマンドラインで unison work ssh://remote.dcs.ed.ac.uk/work と実行しましたが、fatal error: could not connect to server. というエラーが出て失敗します。しかし ssh remote.dcs.ed.ac.uk/work で直接接続してみると、$PATH は設定されていて、Unisonの実行可能ファイルもちゃんとあります。
最初のケースは Unisonが実行時にsshを呼び出し、2番目のケースではsshがあなたにリモートシェルを提供しています。 sshの設定次第では、この2つのシーケンスは異なるものです。
ssh remote.dcs.ed.ac.uk 'echo $PATH'
と打った時の表示と、一旦ログインしてシェルから echo $PATH と打った時と同じ表示が同じか試してみましょう。
これはsshの設定によるものだと思われますが、詳しいことはわかりません。
詳しい人がいたら是非教えてください(訳注: 例えばユーザのシェルの設定とシステム全体の設定で $PATH が異なる場合に、このようなトラブルが起こるものと思われます。2つ下の項目参照)。
Windows上のOpenSSH越しにUnisonが実行できません。原因はわかりませんか?
Antony Courtneyが以下のコメントを寄せてくれました。
私もこのsshクライアントでUnisonを実行させるのに苦労しました。
そして少なくとも一つの問題に行き当たりました。
この経験を共有して、Windows/Unison/ssh/Cygwinの組み合わせで使おうとするユーザに known good な解決法を提供したいと思います。
bashから実行すると(少なくとも私の場合は)失敗します。
unison\_win32-gtkui.exe を実行すると、Fatal error: Error in checkServer: Broken pipe[read()]というダイアログが出ます。
標準エラー出力にはssh: unison_win32-gtkui.exe: no address associated with hostname. という出力がされます。
これはOcaml Win32ライブラリとCygwinの間で、子プロセスに対する argv[] の扱いが異なるためではないかと思います。
解決法として、UnisonをDOSプロンプトから起動する方法があります。
sshでサーバにログインすると、ちゃんと動いているように見えます(Unisonのバイナリにもちゃんとパスが通っています)が、ssh <server> unison は失敗します。何故でしょうか。
Nick Phillipsが以下の説明を寄せてくれました。
簡単なことです。
sshを起動し、パスワードを入れるなどして、最後にログインシェルに行き着きます。
しかし ssh myhost.com unison を実行すると、Unisonはログインシェルから実行されるわけではありません。
これは異なるシェルの設定スクリプトが使われていることを意味します。
同時に、多くの人が間違った設定スクリプトを設定しています。
例えばbashの場合、.bash_profile はログインシェルとして実行した際にだけ使われます。
これはシステムのコンソールか、ターミナルか、もしくはリモートからログインした場合です。
コマンドラインからxtermを実行した場合にはログインシェルは実行されません。
sshやrshでログインした場合、ログインシェルは実行されないでしょう(これはもちろん良いことです。例えばどんなターミナルが使われているかを尋ねるように、そこからインタラクティブにコマンドを実行したいでしょう。)
.bash_profile で $PATH の設定をしたいと言い張る人たちは、以下のどれか一つ以上を実行する必要があるでしょう。
これは他の多くのシェルに関しても言えることです。
- それをやめる
- bashのマニュアルのINVOCATIONのセクションを読む
$PATHを.bashrcで設定する- 管理者にシステムの大本で
$PATHの設定をするように頼む .bashrcから.bash_profileをsourceする...
非常に巨大なディレクトリに対してUnisonを実行するとout of memoryというエラーが出ます。
スタックの最大サイズを増やす必要があります。
例えばLinuxやSolarisのシステムでは、ulimit コマンドを実行します(詳しくはbashのドキュメントを読んでください。)
非常に巨大なファイルをコピーできません。以下のようなエラーが出ます。
Error in querying file information:
Value too large for defined data type [lstat(...)]
これはUnixシステムコールに対するOCamlインタフェースの制限です。 OCamlライブラリがファイルの位置を表現するのに32bitを使っているのが原因です。 OCamlでの正のintの最大値はおよそ2.1E9です。 OCamlの開発チームがいつの日か64bitの整数を用いるインタフェースを提供してくれるのを待ちます。
最初に実行する時、何故Unisonはこんなに遅いのですか?
最初の同期の際、Unisonはレプリカの状態に関する記憶を全く持っていません。 よってUnisonは全てのファイルをチェックし、フィンガープリントを計算し、ネットワーク越しにフィンガープリントを転送し、他方と比較せねばなりません。 一度これが完了するとその情報を蓄えておけるので、次回以降の同期の際にはほとんどの作業をそれぞれローカルに行なうことができるようになります。
プロファイルで指定した path を、コマンドラインの -path オプションでオーバーライドできないのですが。
その通りです。
path は設定を行なう度に、Unisonが同期を行なうリストの中に次々と追加されていきます。
そして一度リストに追加されたpathを削除する方法はありません。
解決法としてはプロファイルを、異なる path を記述した複数のトップレベルのファイルに分け、path 以外の設定に関しては共通のファイルを include する方法があります。
プロファイルに設定した root をコマンドラインからオーバーライドしようとしてもWrong number of roots (2 expected; 4 provided) というエラーが出て失敗します。
root はプロファイルかコマンドラインのいずれかでのみ設定する必要があります。
OCaml 3.04でUnison 2.7.7をコンパイルしようとしていますが、Values do not matchというエラーが出ます。
Unisonの2.7.7はOcaml3.02でコンパイルできます。
それ以降の(3.04を含む)バージョンのデフォルトでは、インタフェースの中で宣言された場合、関数呼び出しへの引数の全てのラベルが必要となります。
解決するにはMakefile.OCamlというファイルに CAMLFLAGS+=-nolabels と追加して -nolabels オプションを有効にします。
2.7.7をGUIをコンパイルする際は、LablGtk 1.1.3の代わりに1.1.2を使ってください。
トリックとTips
Unisonをinetdから実行することはできますか?
私たちは試してはいませんが、Toby Johnsonが詳しいchroot mini-HOWTOを寄せてくれました。(TobyのHOWTOの元になったHOWTOはYan Seinerによるものです。)
Unisonに実行の度にパスワードを尋ねなくさせることはできますか?(そうすれば、例えば30分に一回、シェルスクリプトから自動的に実行させることができます。)
(訳注: この回答は公開鍵認証でssh接続ができるという前提で書かれています。)
実際にパスワードを尋ねているのは、Unisonから内部的に呼び出されたsshです。
UnixでUnisonを実行しているのであれば、ssh-agent を試してみるべきでしょう。
ssh-agent bash
と実行すると、サブプロセスとしてbashが実行されます。
このシェルから ssh-add コマンドで秘密鍵を登録します。
これは実行した際に一度だけパスワードを尋ね、そのセッションが終了するまでそのパスワードを保存します。
これでパスワードを入力せずにUnisonを実行でき、更にはシェルスクリプトから自動的に繰り返しUnisonを実行することもできます。
sshでパスワードを要求しない設定にすることも考えられます。 認証用の公開鍵を作る際に空のパスフレーズを与えれば良いのです。 クライアントにパスフレーズが空の秘密鍵を置いておいても問題ないと思うのであれば、この方法はWindowsマシンでも使うことができます。
WindowsでUnisonをクリックスタートして、特定のプロファイルを使って同期させることはできますか?
Greg Sullivanが以下の有用なトリックを教えてくれました。
Windows 98のマシンでクリックして特定のプロファイルで同期させるには、プロファイルでsshを使っているのであれば、unison profile-name という内容だけ(Unisonの実行可能ファイルがパス上にあるのであれば)を含んだ .bat ファイルを作る必要があります。
最初はデスクトップにショートカットを作り、unison profile-name というコマンドを実行するよう設定したのですが、実行するとハングしてしまいます。
しかし .bat を使うトリックはうまくいきます。
というのも、まず command.com を立ち上げてから .bat ファイルを実行するからです。
sshのポートフォワーディングでUnisonを実行することはできますか?
Mark Thomasは以下の方法でうまくいくと言います。
Windowsでコマンドラインからssh越しにUnisonを使おうとすると問題があったのですが、Unisonは通信にソケットを使えることに気付きました(何て素晴らしいソフトウェアでしょう!)。
そこでTTSSH(http://www.zip.com.au/~roca/ttssh.html)のポートフォワーディング機能を使ってみました。
Unisonを使うには、ポートフォワーディングを有効にしたTTSSHに、Unisonサーバプロセスが走っているLinuxサーバに接続します。
Windowsでは単にUnisonを実行してlocalhostに接続する(unison socket://localhost:XXXX/ ...)だけです。
接続するネットワークによってホスト名が変わるラップトップ上でUnisonを使うことはできますか?
rootalias 機能で使えるようになります。
#####(Unixで)ダイアログボックスではなく、コンソールでパスフレーズを打たねばならないのが面倒です。より良い方法はありますか?
ダイアログボックスにPTYを割り当ててsshとやり取りする等、いくつかのアイディアがあります。 が、まだそれらを実装はしていません。 あなたがハックしてみたいのなら、私たちは喜んでアイディアについての議論やパッチのマージに応じますよ。
一方、tmbがexpectkを使ってその機能を実現するスクリプトを公開しています。 http://www.cis.upenn.edu/~bcpierce/unison/download/resources/expectk-startupから手に入ります。