Unison

出自 ArchWiki

Unison 是一个双向文件同步工具,可在类 Unix 操作系统(包括 Linux、macOS 和 Solaris)和 Windows 上运行。它允许将文件和目录集合的两个副本存储在不同的主机上(或同一主机上的不同磁盘上),分别进行修改,然后通过将每个副本中的更改传播到另一个副本来更新。

安装

安装 unison 软件包,该软件包提供 CLI 和 GTK 界面。

配置

要使用 Unison,您需要创建一个配置文件。

GUI

要使用 GUI 配置 Unison,请运行 unison-gui

手动

或者,在 ~/.unison 中手动创建一个配置文件,并将以下行添加到默认配置文件 ~/.unison/profilename.prf 中。

定义要同步的根目录。

root=/home/user/

定义文件应同步到的远程目录。

root=ssh://example.com//path/to/server/storage

可选地,为 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-gui

并选择配置文件。Unison 具有友好的界面,您可以在其中查看进度和更改。

版本不兼容性

自 2.52 版本起,Unison 实现了对跨版本同步的有限支持。有关详细信息,请参阅迁移文档

对于 2.52 之前的版本,要正常运行,两端必须安装使用相同版本的 OCaml 编译的相同 Unison 版本。

当与另一个发行版同步时,您很可能必须在一端手动编译 OCaml 和 Unison。

技巧与诀窍

节省人工时间和击键

如果在一个能够维护合适的滚动缓冲区的终端模拟器中运行 unison,则无需确认每个非冲突的更改;将 auto 选项设置为 true 以避免这些提示。

更友好的 diff 输出

unison 默认的 diff 命令是 diff -u CURRENT2 CURRENT1。当查看此命令的输出时,可能难以记住从左到右('>')传播与从右到左('<')传播时将保留哪些更改。以下配置使其易于记忆:'>' 保留以 '>' 开头的行

diff = diff -u CURRENT2 CURRENT1 | perl -pe 's/^\+/>/; s/^\-/</'

在 Emacs 中合并

Unison 具有协助用户使用外部合并程序合并两个冲突文件的能力,但默认情况下它不配置此类程序。手册建议

merge = Name *.txt -> emacs -q --eval '(ediff-merge-files-with-ancestor "CURRENT1" "CURRENT2" "CURRENTARCH" nil "NEW")'

这假定您在 X 中运行 Unison,因为合并命令无法在终端中运行(Emacs:“标准输入不是 tty”)。另请注意,Unison 将 CURRENT1 等变量替换为单引号文件名。因此,上面的方法有效,但像 "(ediff-merge-files... \"CURRENT1\" ...)" 中那样通篇使用双引号将不起作用。

使用变量 CURRENTARCH 告诉 Unison 您希望使用公共祖先进行 3 向合并,这只有在先前将“backupcurrent”首选项设置为上次同步时才有可能。要在终端中执行普通的 2 向合并,可以使用以下配置。这也使用 emerge.el,有些人觉得它比 ediff.el 更可取

merge = Name {*,.*} -> urxvt -e emacs -nw -q --eval '(emerge-files nil "CURRENT1" "CURRENT2" "NEW")'

如果使用变量 CURRENTARCHOPT 而不是 CURRENTARCH,那么 Unison 将在公共祖先可用时提供它,否则回退到请求 2 向合并(通过将变量设置为空字符串)。这可以在 shell 脚本中检测到。例如

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

通用配置同步

当同步配置在系统(服务器、工作站、笔记本电脑、智能手机等)之间会发生变化(例如,由于地方性应用程序、安全敏感配置)但仍然包含通用结构(例如,键盘绑定、基本 shell 别名)的配置文件时,最好将此类内容分隔到单独的配置文件中(例如,.bashrc_common),并且仅同步这些文件。

警告: 配置文件的双向同步可能会成为攻击的途径,因为它使对等同步系统能够接收对配置文件的恶意更改(甚至可能是系统与之同步的其他对等方)。对于攻击者来说,这是一个有吸引力的选择,特别是当两个系统的概念安全级别不同时(例如,公共 shell 服务器与个人工作站),因为它可能更容易入侵安全性较低的系统。当认为两个特定系统之间的双向同步不必要时,始终使用 noupdate 选项;必要时,在同步时验证每个更改。应极其谨慎地进行自动双向同步。

使用不同的数据目录

默认的 unison 数据目录是 ~/.unison。此目录将包含配置文件,以及日志和原始数据。如果要更改它,可以设置一个环境变量(在您的 shell 配置中或在使用 unison 命令之前)

export UNISON="my-unison-data-folder"
注意
  • Unison 尚不符合 XDG 标准,有关更多信息,请参见以下问题:issue 270issue 552
  • 在一台机器上设置 UNISON 变量仍将在远程机器上使用 ~/.unison 目录。

参见