Cygwin环境下Unison文件同步工具的使用相信很多人unix程序员都喜欢在windows下写代码,也许因为windows下有很多方便好用的编辑器,如Source Insight,UltraEdit等,也许是不喜欢vi,emacs等。于是就有了很多人在windows下写代码,然后用一些工具,比如scp,将代码再传到服务器上,然后再服务器上编译运行。当然,不排斥个人习惯,也不否认这种方法的可行性。但是这种方法在实际使用当中却是极不方便的,而且更可怕的是这种方法很可能出错。例如,在服务器和本地间进行代码拷贝的过程中,你可能已经记不清楚哪边的代码是最新的修改了。也或许你会有自己的一套策略,例如只在windows下修改代码,保证本地的代码是最新修改,每次讲本地代码传到服务器上进行编译。但是这样未免过于死板,操作过程过于复杂(不要说我懒惰)。而且在一些紧急或特殊情况下,未必你能保证自己不违反自己的原则。:)
最好的办法是在服务器和本地之间能有个文件同步的机制,它能自动告诉你哪一边哪些文件是最新更新过的,并提供可选择的双向的文件同步。那这样的话,不管你在本地(windows)或是服务器上(unix)写代码,你所要做的只是写代码前使用这个同步机制保持现在是在最新修改的代码上进行开发。有没有这样的工具呢?
前几天,ruiheng告诉我们Unison文件同步工具就能帮助实现这些,并传授了使用方法。OK,让我们来看看如何使用unison来完成这些工作。
Unison是一个能够在unix和windows下运行的文件同步工具。它能够在两个不同的主机之间,或是通一台机器的两个不同的目录之间进行文件和目录的同步。它也能够有选择的对某一些或单个文件修改进行同步。
Unison能够以文本和图形两种方式运行。文本方式显然更符合我们的要求,因为可以方便的以脚本的方式运行。
Unison提供两种方法进行远程通信,一种是远程shell方式(Remote shell method),另一种是socket方式(socket method)。远程shell 方式可以使用工具ssh来完成,使用这种方式非常的简单,而且安全。这种方法我们后面马上要介绍到。Socket方式要求通过发送tcp包在两地之间进行通信,而且,这种方式是不能保证安全的。我们这里不是用这种方式,也不作介绍。
Unison的其他原理和详细使用,可以在官方参考手册上找到,我们这里不太多讲解。http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#archives。
我们在这里主要讲解下在本地主机windows下,如何完成服务器和本地之间的代码同步。
我们在本地windows上安装cygwin作为我们的工作环境。因为在cygwin的安装包中本身就包含有unison的软件包(最新版本中包含的为unison2.10.2)。同时cygwin中也包含有openssh的软件包。这两个正是我们需要用到的。
下载并安装cygwin,注意,安装时一定要在安装包中选择安装net目录中的openssh和uility目录下的unison。
还有一个问题就是,我们在使用ssh时,一般都是每次和远程主机进行通信的时候都要输入密码。这样的话非常不方便,有什么办法可以解决这个问题呢?
查看文档的ssh 密钥管理部分,我们可以发现,ssh软件包包含两个非常有用的程序来管理确认密钥,允许用户连接到一个远程系统而无须指定password。这些程序是ssh-agent和ssh-add。
ssh-agent程序如同一个看门人,它根据需要安全地提供对安全密钥的访问。ssh-agent启动后,它就会在后台运行,并且可以由ssh和scp程序等其他OpenSSH应用程序所使用。这就使得ssh程序可以请求一个已经解密了的密钥,而不是在每次需要时向你询问私钥的安全口令。我们先看看ssh-agent是如何运行的:
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XX1O24LS/agent.14179; export SSH_AUTH_SOCK;
SSH_AGENT_PID=14180; export SSH_AGENT_PID;
echo Agent pid 14180;
这样,ssh-agent就已经启动并在后台运行,它输出一些环境变量。Ssh客户端和ssh-agent之间就是使用这些环境变量进行通信的。我们应当设定这些环境变量,用来让ssh知道如何与正在运行着的ssh-agent取得通信。一个最简单的方法就是使用下列命令:
$ eval `ssh-agent`
Agent pid 14187
这样不但启动了ssh-agent,而eval命令告诉shell去执行ssh-agent程序生成的命令。确保你指定的是反引号(`)而不是单引号!执行后,eval `ssh-agent`语句将返回代理的进程标识符。在幕后,SSH_AUTH_SOCK和SSH_AGENT_PID shell变量已经被导出而可以使用。我们可以通过“set | grep SSH”看到它们。
OK,既然这样,我们就正式开始我们的操作。
STEP 1:
进入cygwin环境;
STEP 2:
在shell提示符上输入下列命令:
$ eval `ssh-agent`
STEP 3:
当ssh-agent正常运行了,我们使用ssh-add程序将我们的口令文件添加到运行着的 ssh-agent程序。
$ ssh-add e:/private_key
Enter passphrase:(输入你的密码)
现在我们就可以使用ssh连接远程服务器而不用输入密码了。让我们试试:
$ ssh test.xxx.org –p 32200
不用输密码就能进入了。:)
STEP 4:
使用unison进行文件同步,我们在shell提示符上输入下面命令:
unison -ignore "Name {.svn,*.o,*.tmp,db_autogen.*,local.mk,install.sh}" -fastcheck true e:/esales_trunk ssh://axion@test.xxx.org:32200//home/axion/trunk
unison就会对服务器上/home/axion/trunk目录下的文件和本地e:/esales_trunk目录下的文件进行同步了。同步时unison会按你指定的一些策略进行工作,列出需要同步的文件列表,这是,我们可以选择需要同步的文件。
这里对参数说明一下:-ignore表示忽略后面匹配到的文件,-fastcheck true表示同步时使用文件的创建时间来比较两地文件,如果这个选项为false,unison则将比较两地文件的内容。还有一些选项如-sshcmd可以自己指定一个ssh程序,-backup可以指定在每次同步时备份文件等等。更多细节可以参考手册。
写一个shell程序来执行上面的同步命令是一个很好的方法。
到这为止,cygwin环境下unison文件同步工具的使用就介绍完了。总结一下:简单的说,我们就是使用unison的远程shell的方式(Remote shell method)来完成两远程主机间文件的同步,用到了工具ssh,并使用ssh-agent和ssh-add来管理密钥,完成不需要每次输入密码的ssh连接(passwordless connections)。
其实选用cygwin环境是因为它正好集成了我们要用到两个软件,而且其环境也不是很复杂。我想在windows环境下不使用cygwin,就是用windows版的unison和openssh也应该同样能实现这个同步。在服务器上运行unison进行同步也是一样,linux版的unison可以到官方网站上下载(http://www.cis.upenn.edu/~bcpierce/unison/)。freeBSD版的可以下载,也可以直接从ports上安装。
感想:
我本人是vi的忠实用户,平时写代码都是在服务器上,但有时也会在本地机器上作了一些改动需要传到服务器上。其间我感到不是很方便,而且也不安全。Ruiheng提供的这种方法是一种很好的解决方案,特别是喜欢使用windows下工具写代码的人来说,不可以尝试下哦:)。我在学习使用这个软件的过程中,不但认识了unison,也了解了一下ssh的基本知识,获益匪浅啊。
熊雄斌
2005-08-23