AI活用

把Obsidian每天2次备份到Google Drive。Mac的rsync与日文长文件名的陷阱

把Obsidian每天2次备份到Google Drive。Mac的rsync与日文长文件名的陷阱

早上好,我是まさきん。

我把 Obsidian 的全部笔记,做成了每天备份到 Google Drive 的形式。本以为只是用 Mac 自带的 rsync 复制过去而已,结果因为日文的长文件名失败了一次。估计会有人卡在同一个地方,所以把步骤和规避方法记下来。

※本文为发布时的信息。最新条件请以官方网站为准。

POINT
  • Obsidian 的备份,只要用 rsync 把库(vault)复制到 Google Drive 就能搭起来
  • macOS 自带的 rsync(openrsync),遇到日文长文件名时因为建不出临时文件而失败
  • 加上 --inplace 之后就不再创建临时文件,在我的环境里顺利通过了
  • 用 launchd 每天执行2次。首次是约2万个文件、数GB的规模,退出码为0
  • 机密信息和缓存排除在对象之外,云端那一侧的确认定为每周1次

为什么又多加了一个备份地点

Obsidian 的全部笔记被称为“库(vault)”。我的库,此前一直备份在 GitHub 上。不过,备份地点只有一个,总觉得有点不踏实。

于是,我选了 Google Drive 作为另一个存放处。在电脑版 Google 云端硬盘的“我的云端硬盘”下面准备一个文件夹,然后用 rsync 把增量复制过去。

前些天,我写了退订 Obsidian Sync 的事。笔记的正本已经搬到了 Notion,但库的文件本身还留在手边。既然停了同步,备份这件事我就想自己掌握在手里。

库只是一个普通的文件夹

Obsidian 官方帮助里说,笔记是以 Markdown 格式的文本文件保存的。库就是本地文件系统上的一个文件夹,也包含子文件夹。

设置放在库根目录下的 .obsidian 文件夹里。按说明,快捷键和主题等都放在这里。

也就是说,备份不需要什么特别的工具。把文件夹复制到别的地方,那就是备份了。rsync 之所以能用,多亏了这样的构造。

同步和备份是两回事

Obsidian 官方帮助把同步和备份分开来说明。同步让笔记保持最新。但它提示说,同步并不能防止数据丢失。

项目同步备份
目的让所有设备保持同一状态在别的地方留一份副本
方向基本是双向从源到备份处的单向
删除时删除的结果也会传到别处视设置而定,会留在备份处
损坏时损坏的状态也可能传过去有可能留下传过去之前的版本
这次的角色不使用用 rsync 每天复制2次

这次做的是右边的备份。我不会用 Obsidian 去打开 Google Drive 上的文件夹,它只是作为复制的目的地放在那里。

官方帮助里还有一条注意事项:不要用多个服务同步同一个库,以免数据冲突或损坏。不直接编辑备份处,我认为也和这条注意事项相吻合。

整体构成

整套机制只有3个部件。

  1. 库的文件夹(例:~/Notes)
  2. Google Drive“我的云端硬盘”下的备份文件夹
  3. 调用 rsync 的 shell 脚本,以及定时运行它的 launchd

rsync 负责复制到本地的文件夹。从那里再往上的上传,是电脑版 Google 云端硬盘的工作。脚本不会调用云端的 API。

镜像和流式传输的区别

电脑版 Google 云端硬盘对“我的云端硬盘”有2种处理方式。我把官方帮助的说明整理成了表。

项目流式传输镜像
文件的保存位置主要在云端云端和本地两边
离线使用仅限指定为离线的文件随时可用
电脑的容量几乎不占用占用一份完整副本的量
在 macOS 上的位置~/Library/CloudStorage 下(不可更改)在设置里选择的文件夹

macOS 上的流式传输,会显示在 Finder 侧边栏的“位置”里。默认位置是 ~/Library/CloudStorage,据说不能更改。

从作为 rsync 复制目的地的角度来考虑,大概可以这样整理:镜像方式下,复制的结果也会完整地留在手边,相应地,库和备份会双重占用容量。流式传输可以节省容量,但文件的实体主要在云端那一侧。

哪个才是正解,我想要看磁盘的剩余空间。如果是数GB的规模,镜像的负担也许不大。另外,Obsidian 官方帮助里有关于把库放在 Google Drive 上的说明,内容是要设置成可以离线使用。这讲的是同步的用途,不过思路似乎可以参考。

rsync 的基本命令

骨架大概就是这样。路径用的是一般化的例子。

#!/bin/bash
SRC="$HOME/Notes/"
DEST="$HOME/GoogleDrive/vault-backup/"

rsync -a --inplace \
  --exclude '.venv/' \
  --exclude 'node_modules/' \
  --exclude '.cache/' \
  --exclude 'tmp/' \
  --exclude '.env' \
  --exclude '*.token' \
  "$SRC" "$DEST"
rc=$?
echo "$(date '+%F %T') rc=$rc" >> "$HOME/Library/Logs/vaultbackup.log"
exit $rc

DEST 要换成自己“我的云端硬盘”下的实际路径。如果是流式传输,就在 ~/Library/CloudStorage 下面。

用到的选项不多。

选项含义(man 页面的说明)这次的用法
-a一并指定递归、保留时间等加上
--inplace不创建临时文件,直接写入目的地加上(后文的规避方法)
--exclude排除匹配模式的文件排除机密信息和缓存
-n不实际改动目的地的试运行首次执行之前用来确认
--delete把源里没有的文件从目的地删除加不加取决于方针

加上 --delete 之后,在源里删掉的文件也会从备份处消失,行为就接近同步了。如果想把误删的笔记留下来,我想也可以选择不加。

源路径末尾的斜杠也需要留意。加上的话,复制的是“文件夹里的内容”。不加的话,会连同文件夹一起再深一层地放进去。

哪些东西排除在备份之外

库里面往往会混进笔记以外的东西。我把下面4类排除在了对象之外。

种类例排除的理由
虚拟环境.venv/ 和 node_modules/可以重建。文件数量多
缓存.cache/ 等可以重建。内容变化频繁
临时存放处tmp/ 等没有必要保留
机密信息.env 和令牌文件不想扩大放到云端的范围

我认为判断的轴有2条:能重建的东西排除,泄露了会麻烦的东西也排除。就这2条。

机密信息这种东西,备份地点越多,存放的地方也越多。所以我从一开始就不把它放进对象里。机密信息的找法,在gitleaks 显示“no leaks”却仍漏掉2处的事里也写过。

排除的设定,可以用加了 -n 的试运行来确认。再加上 -v 的话,会把预定要复制的文件列出来。看一看里面有没有出现机密文件的名字,会比较安心。

无需签约也能获得100积分的资费模拟 把备份整理好之后,顺便用 Rakuten Mobile 重新审视一下通信费

点击后会跳转到乐天登录页面,登录后即可看到活动内容。

卡住的地方:因为日文长文件名而失败

第一次执行,中途就停了。原因是文件名很长的日文文件。

报错里出现的是 mkstempat 这个函数名,内容是创建临时文件失败。原因是临时文件的名字超过了255字节。

机制是这样的。rsync 通常会在目的地创建一个临时文件,传输结束后再把它改成本来的名字。samba.org 的 rsync man 页面里,也写了这一默认行为。

临时文件的名字会比原来的名字更长。所以,即使原来的名字刚好在长度范围内,临时文件的名字也可能超过上限。

注意

文件本身明明可以存在,却偏偏在复制的时候失败。这是因为原文件名虽在上限之内,临时文件的名字却超过了上限。习惯用较长的日文给笔记起标题的人,也许很容易踩到。

255字节相当于多少个日文字符

在 macOS 的头文件里,NAME_MAX 被定义为255。注释写的是“文件名的最大字节数”。

下面是计算。日文的大部分字符,在 UTF-8 下是1个字符3个字节。255除以3是85。也就是说,如果是纯日文的名字,大约85个字符是个参考值。混有扩展名或半角字符的话,数字会稍有变化。

另一方面,事情要更复杂一点。在 Apple 的开发者论坛上,Apple 的支持人员还给出了另一种说明:APFS 本身的上限是255个字符,和 NAME_MAX 对不上。那里还写着,上限会因卷的格式而变。

所以,我把“约85个字符”当作偏安全一侧的参考值来对待。实际生效的上限,也许会因复制目的地的文件夹建立在哪种机制之上而变化。

规避方法是 —inplace

对策只是加一个选项而已:--inplace。

openrsync 的 man 页面上说明,它不创建临时文件,而是直接操作目的地的文件。既然不创建临时文件,名字变长的问题也就不会发生。在我的环境里,这样就一路通到了最后。

不过,也有要付出的代价。samba.org 的 man 页面列举的注意事项大致是这些。

这次的目的地,是一个谁也不会打开的备份文件夹。就算停了,下次执行时也会重新复制。所以我判断,在这个用途下这是可以接受的代价。

也有把文件名本身改短的办法。话虽如此,去改约2万个文件的名字并不现实。

macOS 的 rsync 是 openrsync

说到底,Mac 的 rsync 内里已经和以前不一样了。在近年的 macOS 上,自带的 rsync 换成了一个叫 openrsync 的实现。

Apple 公开了 rsync 的源代码。那个仓库里包含 openrsync 目录。man 页面的名字也是“openrsync”。其中说明,它与 samba.org 版的协议27〜29兼容。

切换的时期,据说是在 macOS Sequoia 15.4 前后。不过,在 Apple 的官方发行说明里没能确认到。所以这里就停留在“据说”。

实务上要注意的只有一点:在网上找到的 rsync 例子,不一定能原样运行。要用的选项,最好在自己机器上查一下 man rsync 来确认。

用 launchd 每天运行2次

定时执行交给了 launchd。在 Apple 面向开发者的文档里,cron 虽然还能用,但已不被推荐,文档引导大家使用 launchd。

时间用 StartCalendarInterval 这个键来指定。plist 的骨架如下。任务名和时间只是示例。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.example.vaultbackup</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>/Users/yourname/bin/vaultbackup.sh</string>
  </array>
  <key>StartCalendarInterval</key>
  <array>
    <dict>
      <key>Hour</key><integer>3</integer>
      <key>Minute</key><integer>30</integer>
    </dict>
    <dict>
      <key>Hour</key><integer>13</integer>
      <key>Minute</key><integer>30</integer>
    </dict>
  </array>
  <key>StandardOutPath</key>
  <string>/tmp/vaultbackup.out.log</string>
  <key>StandardErrorPath</key>
  <string>/tmp/vaultbackup.err.log</string>
</dict>
</plist>

按 launchd.plist 的 man 页面,表示时间的字典可以并列多个。每天2次的话,就写2个字典。没写的项目按“全部”处理。

我定在了凌晨和午后这2次。凌晨那次负责收前一天的部分,午后那次负责收上午的工作。

睡眠期间的处理和 cron 不同。Apple 的文档里说,如果在预定时间处于睡眠状态,会在唤醒时执行。

习惯了 cron 写法的人,也请一并看看cron 的日期与星期陷阱的文章。我认为定时执行这种东西,写完之后的验算很重要。

首次和定时执行的结果

首次是约2万个文件、数GB的规模。加上 --inplace 之后的首次执行正常结束,退出码为0。

由 launchd 定时触发的执行,也同样以0结束。手动运行的时候,和定时运行的时候,两边我都确认了,因为运行的环境稍有不同。

不过,这只意味着“成功复制到了本地的备份文件夹”。上传到云端是另一回事。首次上传很花时间。在写这篇文章的时间点,我还没能确认它已经完成。所以,这部分的结果不写。

云端那一侧的确认每周1次

即使 rsync 的退出码是0,也不代表已经送到了云端。所以,我另外安排了一项“有没有送到”的确认。频率只有每周1次。

要看的是2点。

  1. 新旧:云端那一侧的文件是否是最近的日期
  2. 内容:实际打开文件能否读出来

如果只看日期,损坏的文件看上去也是新的。做到打开来读这一步,才称得上是“能恢复的备份”吧。

不每天做,是因为坚持不下去。我认为这里按周来做就足够了。

失败的通知不放在脚本里

失败时的通知,不从脚本里发送。我设计成交给已有的监控机制来处理。

脚本的职责只有2项:复制,以及把退出码留在日志里。就这2项。

要是连通知也塞进去,通知对象的设置和机密信息就会混进脚本里。把监控集中在一处,即使任务增多,要修改的地方也只有一个。

放弃 Time Machine 的理由

既然是 Mac,Time Machine 也是候选之一。Obsidian 官方帮助也把它作为操作系统自带的工具列了出来。

不过,我的 Mac 上还没有设置保存位置,照现在这样是用不了的。按 Apple 的支持页面,它需要外置存储,容量以 Mac 的2倍以上为参考。

这次我没有准备到那一步,就放弃了。Time Machine 是保护整台 Mac 的工具。和这次“只把库转移到别的地方”的目的相比,角色也许稍有不同。

常见的失误与陷阱

把搭建过程中觉得容易绊倒的地方列出来。

我实际踩到的是第一条。第五条,我打算靠每周1次的确认来防范。

开始之前要确认的事

CHECK
  • 库的文件夹的位置,以及大致的文件数量和容量
  • Google Drive 的剩余容量,以及电脑磁盘的剩余空间
  • “我的云端硬盘”用的是流式传输还是镜像
  • 库里有没有 .env 或令牌文件
  • 有没有日文超过80个字符那样的长文件名
  • 用 -n 试运行,复制的对象是否符合预期

常见问题

Q. Obsidian 的备份只放 Google Drive 够吗?

只有一处的话,那里用不了的时候就麻烦了。Obsidian 官方帮助也说明,云端既是物理存储的替代,也是它的补充。我做成了和 GitHub 并用的两处。

Q. 可以直接打开放在 Google Drive 上的库吗?

Obsidian 官方帮助里说,通过 Google Drive 进行同步并不受官方支持。这次的构成也是以不打开备份处为前提。我认为只在原来的库里编辑才安全。

Q. --inplace 可以一直加着吗?

要看用途。man 页面里有一条注意事项:传输过程中目的地会处于不完整的状态。如果是谁也不会打开的备份处,可以说影响很小。

Q. 安装 Homebrew 的 rsync 这个方法怎么样?

也有另外安装 samba.org 版 rsync 的方法。不过我没有试过。这次是用加上 --inplace 的方式来应对的。

Q. 每天2次会不会太多?

rsync 只复制差异部分。没有变更的话,几乎什么都不做就结束了。增加次数负担也很小,所以也许可以按“丢了也无妨的时间跨度”来决定。

Q. Mac 处于睡眠状态时会怎样?

Apple 的文档里说,睡眠期间错过时间的任务会在唤醒时执行。关机状态下如何处理,需要另行确认。

Q. 在源里删了笔记,备份处也会消失吗?

没有加 --delete 的话,会留在备份处。加了的话,源里没有的文件也会从备份处消失。选哪一种,取决于你对备份的期待是什么。

Q. 上传有没有完成,在哪里看?

可以在电脑版 Google 云端硬盘的应用里确认同步的状况。首次上传是否完成,我还没能确认。打算在每周1次的确认里,一直看到能打开来读为止。

参考的官方信息

总结

Obsidian 的库只是一个普通的文件夹。所以,只靠 rsync 和 launchd 就搭起了每天的备份。

卡住的地方是日文的长文件名。加一个 --inplace 就能通过,但要付出代价这一点还是应该知道。

是否送到了云端,接下来才要确认。不妨先从 -n 的试运行开始,用手边的库试一试吧。

把备份这样的“每月的机制”整理好之后,每个月的通信费也许也能用同样的眼光重新审视。

无需签约也能获得100积分的资费模拟 每个月的通信费也用 Rakuten Mobile 确认一下

点击后会跳转到乐天登录页面,登录后即可看到活动内容。

本文包含联盟营销广告。如果您通过本站链接申请相关商品或服务,我们可能会从合作企业获得报酬。此外,运营者是乐天集团的员工,也可能通过员工推荐计划获得报酬。文章内容与评价均基于运营者的真实体验与调查完成,与是否存在广告无关,但请您在阅读前了解上述关系。详情请参阅免责声明与联盟营销说明。 免责声明与联盟营销说明

本文包含机器翻译内容。正式条件请以乐天移动官方网站的多语言页面为准。

如果您对乐天移动的通信区域·信号状况有疑问,可以通过官方的 电波改善调查申请表 进行咨询。

ABOUT THE AUTHOR
まさきん

乐天集团员工·数字营销人(持有FP资格)

40岁出头,双职工家庭、四个孩子的父亲。在乐天集团担任数字营销工作的同时,也活用理财规划师(FP)资格,专注于家庭理财与资产配置。

查看简介

相关文章

RELATED
Gemini(Google AI Pro)家庭共享最多5名家人|设置步骤与共享范围 AI活用

Gemini(Google AI Pro)家庭共享最多5名家人|设置步骤与共享范围

Google AI Pro除管理员外最多可与5名家人共享。Gemini App和存储空间可以共享,YouTube Premium Lite仅限管理员,Flow的上限由全家分摊。本文根据官方帮助整理了设置步骤和儿童账号的处理方式。

2026.10.13 · 阅读约9分钟
AI订阅扣款日与记账对不上的3个原因|Claude升级后扣款日会改变 AI活用

AI订阅扣款日与记账对不上的3个原因|Claude升级后扣款日会改变

Claude在月中升级到Max时,计费周期会重置,当天成为新的扣款日。美元换算日元的汇率在数据到达发卡公司时确定,账单和记账App的同步也会晚几天。本文整理了以收据邮件为准来确定月份的5个步骤。

2026.10.13 · 阅读约10分钟
把freee会计的未处理明细改成每月一次的核销班次:每月5日7:30、分3类、最多15条交给人处理的设计 AI活用

把freee会计的未处理明细改成每月一次的核销班次:每月5日7:30、分3类、最多15条交给人处理的设计

freee会计里有大约18条未处理明细,连续6次每周检查都原封不动地留着。这里整理一下每月5日早上7:30在家里的Mac上运行的核销班次的设计,以及“能确定的部分每月合并成1个任务、拿不准的明细逐条交给人、上限15条”的界线。

2026.10.12 · 阅读约11分钟
转到乐天移动,最高可获14,000积分 无需签约也能获得100积分的资费模拟 →
立即申请 →