Unison 是一个文件同步工具,采用 rsync 类似的算法,但是提高了一步,双向同步以及一个统一的版本控制系统。
可以用如下格式调用 unison
unison profile_name [options]
读取 ~/.unison 目录下的配置文件 "profile_name.prf"。
注意到命令行没有指出要进行文件同步的两个地址,实际上应该在配置文件 <profile_name.prf> 中有相关的 root 指令进行了设置。如:
# Roots of the synchronization root = /home/bcpierce root = ssh://saul//home/bcpierce # Paths to synchronize path = current path = common path = .netscape/bookmarks.html
unison profile root1 root2 [options]
root1, root2 分别是要执行同步的两个路径。这时 "profile.prf" 配置文件中,应该不包含 root 设置;
root1, root2 路径的格式可以是本地目录,也可以是远程服务器的路径,例如: ssh://username@remotehost//home/jiangxin/work
unison root1 root2 [options]
相当于 unison default root1 root2。即读取 "default.prf" 的配置。
-testserver
测试连通性,连接到服务器即退出。示例:
$ unison / ssh://opensou1@bluehost/ -servercmd=~/bin/unison -testserver
如果服务器端 unison 可执行文件不在默认目录下,甚至没有 unison 命令(需要你编译一个上传到服务器),则需要使用 -servercmd 参数告诉要执行的服务器 unison 命令位置。
使用 -testserver 参数,则成功链接即退出,也不会去执行目录的比较等后续操作。
-servercmd xxx
告诉 unison, 服务器端的 unison 命令是什么。参见上面的示例。
-auto
接受缺省的动作,然后等待用户确认是否执行。
-batch
batch mode, 全自动模式,接受缺省动作,并执行。
-ignore xxx
增加 xxx 到忽略列表中
-ignorecase [true|false|default]
是否忽略文件名大小写
-follow xxx
是否支持对符号连接指向内容的同步;
例如在我的 ~/.unison 的配置文件 default.prf 中有
# Unison preferences file follow = Path {unison_*} ignore = Path {WWWROOT/wiki_mirror} ignore = Name {,.}*{.~$lock} ignore = Name {a.out}
我将预进行同步的系统文件在 xxx/src 下分别作符号链接,如 unison_httpd.conf 指向 c:/program files/apache/.../httpd.conf。 同步时,"follow = Path {unison_*}" 配置(或参数)将跟踪符号链接指向的实际文件。 如果没有该设置,符号链接不予同步。
-immutable xxx
不变目录,扫描时即忽略
-silent
安静模式
-times
同步修改时间
-path xxx 参数
只同步 -path 参数指定的子目录以及文件,而非整个目录。例如
unison /home/username ssh://remotehost//home/username \ -path shared \ -path pub \ -path .netscape/bookmarks.html
如下参数 ignore/ignorenot, follow, sortfirst/sortlast, backup, merge 定义各自的匹配模式。 例如: ignore = pattern
pattern 的语法格式
Regex regexp
即常规表达式。
Name name
路径的最后一部分与 “name" 匹配。可以使用通配符,见下面描述。
Path path
全路径与 "path" 匹配。可以使用通配符,见下面描述。
以下通配符可以用在 Path 和 Name 中:
?
匹配除了 "/" 之外,任意单个字符;
*
匹配除了 "/" 之外的任意字符;如果用在 "Name" 中,则不和以 "."开始的文件匹配,而用在 "Path" 中,可以和 "." 开始的向匹配。
[xyz]
匹配 {x,y,z} 中任一字符;
{a,bb,ccc}
匹配 a, bb, ccc 中任何一个;
示例:
忽略 CVS 目录以及以 .cmo 结尾的文件:
ignore = Name {CVS,*.cmo}
忽略路径 a/b:
ignore = Path a/b
忽略路径 */tmp。当 * 用在 Path 中,可以和以 "." 开始的文件、目录名匹配,如下面的和 ".foo/tmp" 匹配;
ignore = Path */tmp
忽略 a/b/ 开始,结尾是 .ml 的文件。
ignore = Regex a/b/.*\.ml
本地目录间的镜像
unison <目录1> <目录2>
获取远程 unison 版本
ssh remotehostname unison -version
测试
unison -testServer 本地目录 ssh://user@remotehostname/远程目录
执行数据同步
unison <本地目录> ssh://remotehostname/<远程目录>
远程目录是绝对目录,不是用户主目录
注意 在主机和目录间又多加了一个 "/":
unison <本地目录> ssh://remotehostname//<绝对路径>
参数 -path 指定同步的子目录。以下只同步 /home/username 下的 shared 目录。
unison /home/username ssh://remotehost//home/username -path shared
-path 可以多次出现
unison /home/username ssh://remotehost//home/username \ -path shared \ -path pub \ -path .netscape/bookmarks.html
~/.unison 目录保存用户配置文件以及 Archive 文件。
配置文件扩展名为 .prf,缺省的配置文件为: "default.prf"。
Archive 文件可能有多个,每对同步的对象对应一个文件。这个文件记录了文件的状态,可以在后续的更新动作中更快速的判断文件的更新动作。 Archive 文件名和双方的主机名、路径名等相关。
Archive 虽然自动由 unison 维护,但是特殊情况下(如本机的地址经常变更),可以利用下面的方法:
环境变量 "UNISONLOCALHOSTNAME" 可以用于本机地址经常变化的环境,unison 会采用该环境变量的值;
可以在缺省的配置文件中,用 rootalias 命令将新的主机、路径名称对应为老的主机名和路径名, 然后再确定出 archive 名称。这样就不会造成由于主机名修改,导致 unison 更新状态的丢失, 进而导致上次更新状态的丢失。
rootalias = //new-hostname//new-path -> //old-hostname//old-path
如果 unison 只带一个参数执行,如
unison <name>
则在 ~/.unison 目录下查找 "<name>.prf" 配置文件。
如果不带参数执行 unison,则查找 "default.prf" 文件。
简单的 default.prf 示例
# Roots of the synchronization root = /home/bcpierce root = ssh://saul//home/bcpierce # Paths to synchronize path = current path = common path = .netscape/bookmarks.html
更复杂的配置文件:
# Roots of the synchronization root = /home/bcpierce root = ssh://saul//home/bcpierce # Paths to synchronize path = current path = common path = .netscape/bookmarks.html # Some regexps specifying names and paths to ignore ignore = Name temp.* ignore = Name *~ ignore = Name .*~ ignore = Path */pilot/backup/Archive_* ignore = Name *.o ignore = Name *.tmp # Window height height = 37 # Keep a backup copy of the entire replica backup = Name * # Use this command for displaying diffs diff = diff -y -W 79 --suppress-common-lines # Log actions to the terminal log = true
使用 include 包含文件
"unison workingset" 参照 "workingset.prf" 执行:
path = current/papers path = Mail/inbox path = Mail/drafts include common
"common" 文件内容:
在 common 包含文件中,没有出现 PATH,毕竟要在包含文件中包含各个配置文件的交集么。
# Roots of the synchronization root = /home/bcpierce root = ssh://saul//home/bcpierce # (... other preferences ...) # If any new preferences are added by Unison (e.g. ’ignore’ # preferences added via the graphical UI), then store them in the # file ’common’ rathen than in the top-level preference file addprefsto = common # regexps specifying names and paths to ignore ignore = Name temp.* ignore = Name *~ ignore = Name .*~ ignore = Path */pilot/backup/Archive_* ignore = Name *.o ignore = Name *.tmp
和远程服务器同步大量数据,上传一部分数据后,超时:
9% 559:15 ETARead from remote host bluehost: Connection reset by peer Fatal error: Lost connection with the server
Google 搜索类似问题:
该文章提出增大 ssh 超时时间设置: http://groups.yahoo.com/group/unison-users/message/3403 hello users, I am trying to run unison to sync up 2 different servers. The directory I am syncing is pretty large... about 3000 subdirs and each of those subdirs has a couple dozen dirs under them. About 80 GBs of data total. I am using the following command: unison -batch /dir/path ssh://remoteserver//dir/path I originally used rsync to move the directory over to the remote server however I now have a need for bidirectional mirroring hence the reason why I now use unison. When I run this command, I get the usual warning about no prior index found since this is the first run. Unison then begins to list all the dirs and subdirs (building the index dbase I suppose). When it's almost finished, I get the following lines: Waiting for changes from server Fatal Error: Lost connection with server I have used unison before to mirror directories between these two machines, but none of which were this big with so many subdir branches. Nothing in any logs to give me any clues. I though it might be some sort of ssh timeout, so I added "ConnectTimeout 10" in /etc/ssh/ssh_config to give it a 10 second timeout, but I dont think this will help since the ssh session does indeed connect initially. ulimit -s shows I have an 8MB stack size. Can anyone shed any light onto this problem? Thank you
另外一个用户提出将一个任务分解成多个任务的方法:
http://groups.yahoo.com/group/unison-users/message/3651 The connection between the client and the server can remain idle for a long time when checking for updates. So, if there is a masquerading router (or a firewall using stateful inspection) between the client and the server, it may wrongly consider that the connection is dead after some time. The usual workaround is to use the path directive to synchronize smaller parts of the replica at a time. This should necessary only for the first synchronization, as the subsequent ones are much faster. You could also try to use the ServerAliveInterval directive of ssh in order to keep the connection active.
实际操作中,第一次,我先把要上传的文件打成包,用 ftp 上传,然后展开到服务器中,之后执行一次 unison 同步即可。
Copyright © 2006 WorldHello 开放文档之源 计划 |