我需要在我的计算机和本地网络中的 NAS 之间设置同步。不过设置过程有点复杂,所以我猜想没有现成的产品可以满足我的需求。
细节:
我使用的设备:
- 台式电脑,双启动 Windows 10 / Arch Linux
- 笔记本电脑(Arch Linux)
- NAS(自建,运行FreeNAS)
到目前为止我已经使用它rsync
来备份到 NAS(单向,我的双启动设置对两个操作系统使用相同的存储)。
问题是,我想让笔记本电脑同步。因此我需要进行某种双向同步。
这里出现的问题:
我经常在关机前几秒钟保存文件,因此我需要监视文件更改,而不是定期运行同步工具
- 我无法在本地网络之外同步我的笔记本电脑(在本地网络中,我大多数时候使用台式电脑);本地(更新)版本可能相当过时并会引起一些冲突。
我确实只想使用本地网络(可能是 NAS 的现有网络共享),而不是 ownCloud 或类似的东西,因为我住的地方带宽非常有限,而且我有一些相当大的文件需要保持同步。
我的想法
我发现了这个问题:如何设置 rsync 和任何其他脚本来模拟 DropBox 的最小可行副本?,并研究了使用的解决方案同步(实时同步守护进程),用于将本地目录与远程目标同步。这可以解决问题 1,但我仍然需要做好冲突的准备。此外,我找不到有关 Windows 上 lsyncd 的任何文档,因此我认为它在那里不起作用。
我还研究了将齐奏找到解决方案;它似乎可以进行双向同步。也许我可以将它与 lsyncd 一起使用。不过,我不确定冲突处理。我发现一个提示,使用 ,-batch
冲突就会被跳过。但从长远来看,我该如何处理冲突文件(毕竟我想同步它们)?
所以我的问题是,我该如何实现这一目标?
答案1
取决于你的 NAS - 我非常喜欢BitTorrent 同步为此。它可在大多数系统上运行(包括 raspberry pis 和 mips 系统),并得到相当多的消费者 NAS 系统(如我的 seagate)的支持。您只需选择一个要共享的文件夹,生成一个密钥,然后使用该密钥在您想要的每个系统上设置共享。它足够智能,可以检测到您在 LAN 上,并在 LAN 之外工作。免费版本足以满足我的需求 - 我主要使用它来同步我一直使用的系统的下载以及我不经常添加的许多小文件的备份。
它会满足您的需要 - 单向或双向同步,必要时可使用局域网。它通过保留已删除文件的副本来处理冲突(我根据自己的使用情况关闭了此功能),并且通常运行良好,我几乎注意不到它。
答案2
因此,我自己开发的解决方案需要比Journeyman Geek 的一员。 我用了unison
对于同步部分和zenity
警告冲突。
脚本
bash 脚本(将其放入您的启动应用程序中):
#!/bin/bash
if [ -z "$(arp | grep MAC_ADDRESS_OF_NAS)" ]; then
zenity --warning --text="NAS not found. Aborting."
fi;
unison sync -batch=true -repeat=watch |& while read -r line; do
if test -n "$(echo $line | grep skipped:)"; then
zenity --warning --text="$line";
fi;
done
一致配置(将其sync.prf
放入~/.unison/
):
root=/home/my-username/the-data-i-want-to-backup/
root=/mnt/NAS/some/sub/path/
# follow all symlinks
follow = Path *
# automatically do everything (if there are no conflicts)
auto = true
# for some reason unison fails if I sync the permissions
perms = 0
dontchmod = true
详细解释(以及衍生产品的疑难解答)
- 首先,我检查 NAS 是否在本地网络中。如果其 MAC 地址未出现在输出中
arp
,则我假设我不需要同步。这可能需要进一步调整,因为我很少完全关闭笔记本电脑,因此当我连接到网络时,脚本不会启动。也许我会添加一个 cron 作业或某种“网络连接” zenity
可用于从 bash 脚本创建图形对话框。您可能需要安装它。基本用法非常简单。unison sync
开始同步。它会查找名为 的配置文件~/.unison/sync.prf
。我可以sync
用其他名称替换它(在文件名和命令中)。- 为了跳过冲突的文件,我指定了
-batch=true
。我没有在配置文件中执行此操作,因为unison sync
如果发生冲突,我想手动运行。 - 我不需要第三方工具来观察变化:
-repeat=watch
它完全符合我的要求。 旁注:实际上它会对任何更改开始完全重新同步,因此它可以做得更好,但这对我来说没问题。 - -command的输出
unison
有点奇怪,花了一些时间才让它工作:- 如果存在冲突,则输出包含
skipped: FILENAME
- 这似乎发生在 STDERR 上,而不是 STDOUT 上,所以我需要用管道
|&
- 由于某种原因,我无法弄清楚它对我来说不起作用
grep
。我尝试了类似 的操作unison sync ... |& grep "skipped:" | xargs zenity --text="{}"
,但直到 unison 最终完成时它才会执行(没有 也可以正常工作-repeat=
,没有 也可以正常工作grep
)
- 如果存在冲突,则输出包含
- 出于上述原因,我坚持使用 while 循环来读取输入,并仅在每行本身上使用 grep
- 在 unison 配置文件中,请注意我使用了绝对路径。出于某种原因,它无法与
~/my/folder
补充笔记
我是一个倾向于过度设计的人。我设置了一个脚本来生成 unison-profile。如果您感兴趣的话:
#!/bin/bash HOME_DIR=$(cd ~; pwd) REPO_DIR="$(dirname "$(readlink -f $0)")" UNISON_PRF=$HOME_DIR/.unison/sync.prf # write sync script read -e -p "Local sync dir: [like ~/Data] " LOCAL_SYNC_DIR # make path absolute: LOCAL_SYNC_DIR="${LOCAL_SYNC_DIR/#\~/$HOME_DIR}" read -e -p "Remote sync dir: [like /mnt/NAS/Data/] " REMOTE_SYNC_DIR REMOTE_SYNC_DIR="${REMOTE_SYNC_DIR/#\~/$HOME_DIR}" rm "$UNISON_PRF" echo "root=$LOCAL_SYNC_DIR" > "$UNISON_PRF" echo "root=$REMOTE_SYNC_DIR" >> "$UNISON_PRF" cat "$REPO_DIR/sync.prf" >> "$UNISON_PRF" # user info echo "IMPORTANT: You need to put $REPO_DIR/unison/sync.sh to your startup applications for this to work properly!"