ハチハチイチナナイチ  Index  Search  Changes  RSS  Login

Unisonマニュアル - アドバイス

FAQ

Unison と rsync の違いは何ですか?

端的に言ってしまえば,rsync はミラーリングツールで,Unison はシンクロナイザです.つまり rsync には「このレプリカが最新バージョンですから,もう一方をこれで上書きしてください」と指示する必要があるのですが,Unison はレプリカをそれぞれ見比べて,どちらでもう一方を上書きすべきか勝手に判断してくれます.

Unison も rsync も,更新には Andrew Tridgell と Paul Mackerras による rsync アルゴリズムを用いています.これは巨大なファイルの一部分のみが変更された場合に,転送効率を最適化するアルゴリズムです.

Unison と CVS の違いは何ですか?*1

両方とも,中心となるリポジトリの内容に応じて,ディレクトリ構造からなるリモートのレプリカを最新に保つことができます.また双方向にファイルの更新を行なったり,衝突する更新を検知したりもできます.同時に,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 からダウンロードできます.

また (ソケットモードでサーバに接続しているユーザは) アイコンに細工することでウィンドウを消してしまうこともできます.実行可能ファイルに対してショートカットを設定しているなら,プロパティを設定してそのウィンドウが最小化された状態で表示することができます*2

推移的に用いた場合でも 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 が,中止されるとファイルシステムを良くない状態にするような動作を行なう時にコミットログとして用いる*3 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 の設定によるものだと思われますが,詳しいことはわかりません.詳しい人がいたら是非教えてください*4

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 の設定をしたいと言い張る人たちは,以下のどれか一つ以上を実行する必要があるでしょう.これは他の多くのシェルに関しても言えることです.

  1. それをやめる
  2. bash のマニュアルの INVOCATION のセクションを読む
  3. $PATH を .bashrc で設定する
  4. 管理者にシステムの大本で $PATH の設定をするように頼む
  5. .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 から手に入ります.

Name: Comment:

*1 訳注: まずはファイルシンクロナイザである Unison とリビジョン管理システムである CVS の本質的な違いを押さえておくべきでしょう.

*2 最小化ですから,タスクバーからも消してしまうことはできませんが.

*3 accounting/fedscwh3qt2000.wb3 という実際の場所に対して accounting/fedscwh3qt2000.wb3.unison.tmp という名前で残っている一時ファイルと同様のものです.

*4 訳注: 例えばユーザのシェルの設定とシステム全体の設定で $PATH が異なる場合に,このようなトラブルが起こるものと思われます.2つ下の項目参照.