笔者没有使用 Obsidian 插件进行同步,而是直接将 Obsidian 仓库建立在 OneDrive 中进行同步,这样说最无感的。但是目前 iOS 端 app 只能支持打开 iCloud 同步的仓库。所以目前将 OneDrive 作为主要仓库,iCloud 作为镜像(因为对我的需求而言,移动端仅做查看功能)。
该方案的原理是在 Obsidian 退出时,或间隔一定时间内执行 rsync
命令进行同步,有一个插件可以帮到我们:Shell Commands
在插件中可以添加自己的命令来执行,不过不支持 shell 脚本,只支持单行命令。每一行都是一个命令。所以需要把我们的脚本转换为单行脚本:
1 | if [ -d "/Users/rainy/Library/Mobile Documents/iCloud~md~obsidian/Documents/" ]; then rsync -av --delete --iconv=UTF-8,UTF-8 "/Users/rainy/OneDrive/应用/Obsidian/" "/Users/rainy/Library/Mobile Documents/iCloud~md~obsidian/Documents/"; fi; |
由于我有两台 mac 都会使用,一台是工作机,该机器没有个人的 iCloud 账户,所以不需要同步。这里用一个目录判断来区分,在 iCloud 中有 Obsidian 的目录则证明是私有 mac 端,执行同步,将 OneDrive 中的文件全量镜像到 iCloud 中。第二行原理一致,将 OneDrive 的内容同步到 Dropbox 中,作为二次备份。
然后在事件中设定出发条件,这里我选择没 600s 即十分钟进行一次同步。还有关闭 Obsidian 前同步。
注意:选择关闭 Obsidian 前同步,可能会导致命令执行到一半退出。所以建议先手动同步一遍,后续的增量同步改动不大,基本可以确保同步完成。
rsync 的坑
mac 本身的 rsync 工具是 2.*
的版本,同步包含中文文件名的文件时会有一些问题(乱码,执行中断等)。所以需要手动升级到 3.* 的版本,因为支持 --iconv
参数。但是在 Obsidian 中,用 brew 安装新版本后不会默认使用 rsync 的新版本,所以上面的命令中手动写全路径 今天发现可以在插件中设置环境变量/usr/local/bin/rsync
来使用。
1 | /usr/local/bin |
第一行是 intel 芯片执行文件的路径,第二行是 arm 芯片执行文件路径。在系统变量前可正确识别新版本的 rsync.
关于读取权限的坑
Obsidian 执行脚本时可能没有权限访问网盘内容,可以手动执行命令调用对话框允许访问。
-EOF-