惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
A
About on SuperTechFans
NISL@THU
NISL@THU
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
美团技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
小众软件
小众软件
博客园 - Franky
罗磊的独立博客
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
MongoDB | Blog
MongoDB | Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog
The GitHub Blog
The GitHub Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
Hacker News - Newest:
Hacker News - Newest: "LLM"
Cyberwarzone
Cyberwarzone
C
CXSECURITY Database RSS Feed - CXSecurity.com
Project Zero
Project Zero
Security Latest
Security Latest
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
The Hacker News
The Hacker News
I
Intezer
J
Java Code Geeks
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Privacy International News Feed
月光博客
月光博客
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园_首页
WordPress大学
WordPress大学
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tor Project blog
博客园 - 三生石上(FineUI控件)
The Last Watchdog
The Last Watchdog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org

Dejavu's Blog

甲骨文 ARM 实例部署 Gemma 4 模型 Headscale + Tailscale 组建虚拟专用网 在 Linux 上使用 Yubikey OpenPGP 应用 BuyVM VPS 块存储挂载教程 Alpine Linux 服务器配置指南 Alpine Linux 安装 Cloudflared Docker 多容器共享中心数据库 安装 Komari 服务器监控工具 Scaleway VPS 安装 Debian Linux Debian 13 下部署 AsmBB 论坛 使用 Kopia 自动化备份服务器数据 给 Docker 启用 IPv6 支持 Netcup 服务器安装自定义 ISO 镜像 烽火 HG5582A 光猫开启桥接模式 Docker 自托管 Shlink 短链服务 部署 Obsidian LiveSync 实时同步服务指南 我的 2025 年不完全回顾 Linux 下 Intel 核显驱动配置与硬件加速 Fedora Linux 安装配置记录 2025 年优雅地自托管 RSS 服务 Woodpecker CI 和 Gitea 实现 Hugo 自动部署 Gitea/Forgejo 集成 Woodpecker CI/CD 在 Blinko 中使用 Ollama 作为 AI 供应商 Docker 部署 Gitea/Forgejo Plausible CE 启用城市级地理位置识别 Blinko 开源 AI 知识库 Docker 部署指南 Netcup 免税账号注册及购买服务器全记录 Docker 自托管 Cloudreve Pro 私有网盘服务 GiffGaff SIM 卡使用体验和注意事项 简体中文互联网在变得糟糕吗? 如何低成本申请 S/MIME 证书用于个人邮件服务 迁移到 NameCrane Mail 域名邮箱套件服务 香烟与咖啡 在 Windows 中使用 Yubikey 的 OpenPGP 应用 Windows 11 IoT LTSC 养老指南 巧用浏览器生成 HAR 文件批量下载所需网页资源 聊聊静态网站的评论系统 在 Hugo 站点中优雅地展示实况照片 使用 snac 部署一个简洁优雅的 ActivityPub 实例 当 25 岁来临的时候 断网的这两年 从 Bitwarden/Vaultwarden 到 KeePassXC 也许是 Android 上最好的本地播放器 - 椒盐音乐 2023 半年小结 写一个好玩的 Hugo 货币汇率转换短代码 写一个 Hugo 短代码将不同类别的总字数统计转换为书名显示 海信 Touch Lite 墨水屏音乐阅读器的简单体验 从 Debian 11(bullseye) 无感升级到 Debian 12(bookworm) 使用 GitHub Actions 自动提交 URL 到 IndexNow 批量重写 Git 历史提交记录 使用 cgit 托管小小的也很可爱的 Git 服务器 在 Debian 上使用 stagit 和 Nginx 的简单 Git 服务器 托管简单 Git 服务器的一些尝试 使用 stagit 自托管纯静态 Git 存储库 使用 Docker 快速部署单人 Fediverse 实例 我是如何建立自己的个人博客的? 简单、隐私友好的谷歌分析替代品,Plausible 自托管部署指南 服务器使用 Cloudflare CDN 的最佳实践 甲骨文服务器分配并启用 IPv6 地址 Git 版本控制学习笔记(二) Cloudflare WAF 防护策略简易指南 Mastodon 服务器批量导入自定义表情 低成本自托管 Mastodon 实例简明指南 自托管服务指南──有了服务器可以做什么? 使用 Miniflux + RSSHub 打造个人 RSS 阅读器 构建支持多种 CPU 架构的 Docker 镜像 一个可自托管的静态短链接应用 别了,二〇二二! Duplicacy CLI 进阶使用指南 初探 Cloudflare 零信任 - 通过 Docker 部署 Bitwarden 密码管理器 Yubikey 转运日志及上手指南 初探 Cloudflare 零信任 — 通过 Cloudflare Tunnel 搭建 SSH 聊天室 初探 Cloudflare 零信任 - 通过 Cloudflare Tunnel 访问服务 某科学的 PGP 算号指南 2022 年的 MacBook Air M1 使用体验及应用推荐 使用 Vercel 和 Supabase 自托管 Cusdis 评论系统 为什么你的搜索引擎不好用? 个人在 Windows 上常用软件清单 macOS 基础开发环境设置指南 在 macOS 上使用 Canokey 的 OpenPGP 应用 提取 Windows UWP 应用商店的安装包以供离线安装 Git 版本控制学习笔记(一) 使用 Notion 管理 GitHub Star 项目 使用 Vercel 免费部署 Giscus 评论系统 将博客评论从 Utterances 无缝迁移到 Giscus Canokey 签名和认证应用指南 Canokey 的基本使用指南 Canokey Pigeon 揽件日志及简单开箱 关于 Google Play 保护机制和 DRM 安全等级的那些事 记录一次捡垃圾装机 GitHub 使用 GPG 密钥提交签名认证 使用 Scoop 管理 Windows 下的软件和开发环境 Windows Terminal+PowerShell 7 打造 Windows 下最好用的终端 一个好用的 Telegram 文件批量上传/下载工具 Clash for Windows 优雅地使用 TUN 模式接管系统流量 全平台搭建 Hexo 静态博客指南 尝试将 Manjaro 作为主力操作系统使用 Hexo 进行 SEO 优化的基本指南 使用本地代理给 Git 和 NPM 加速 使用 flowerss 部署 Telegram RSS 订阅机器人
Duplicacy CLI 备份工具的基本使用
Dejavu Moe · 2022-12-04 · via Dejavu's Blog

前言

有个朋友,在 Oracle 免费服务器上托管 Vaultwarden,在没有做过数据备份的情况下,账号被扬了 😆

Unlucky Guy

我也喜欢自托管一些服务,有些数据需要定期的备份,但是我比较懒,偶尔手动备份一下。有了上面倒霉蛋朋友的经历,不得不好好整一下备份服务了。对于涉及敏感信息文件的备份,我认为至少要满足三点:

  1. 安全 使用可靠的加密方式保护对备份的访问
  2. 版本快照 可以在快照之间滚动版本
  3. 自动化 高度可拓展性,定时执行任务

介绍

满足要求的备份服务有很多,但是 Duplicacy 最强大的功能是在支持多种存储服务的条件下,还支持多个实例备份到同一个存储服务。这多个实例之间无需互相通信,且不依赖其他的备份。

Duplicacy 的文档集合的不是很全面,一些较新的说明或举例都分散在 Duplicacy 社区 里。在国内看起来热度不是很高,但是国外用户量挺大的,社区也确实比较活跃,看大牛们秀各种神奇的操作。作者应该是一个国人独立开发者,CLI 软件源码开放,但是它并不是自由软件。只不过对于 个人非商业用途 它是 完全免费 的,这对我个人已经足够了。

本文只记录了基本命令的一些说明和注意点。可能还不是很全面。关于 自动化任务进阶使用 请看下一篇 Duplicacy CLI 进阶使用指南

总之,本文又臭又长,东拼西凑,毫无逻辑。如果您完全看不下去,请不要怀疑,绝对是我的问题!

截止本文时间,Duplicacy 支持的存储服务有:

不同的存储服务在 Duplicacy 中使用的 URL 可以在 Storage Backends 查看,本文我会以 OneDrive Buisness 为例。

安装

Duplicacy GUI 会包含 CLI 程序,本文只介绍 Duplicacy CLI

在 Duplicacy CLI 的 Releases 页面下载编译好的二进制文件

# 选择系统或架构使用 Wget 下载
# Linux x64
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_linux_x64_3.0.1

# Linux x86
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_linux_i386_3.0.1

# Linux ARM
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_linux_arm_3.0.1

# Linux ARM64
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_linux_arm64_3.0.1

# FreeBSD x64
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_freebsd_x64_3.0.1

# macOS x64 (Intel)
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_osx_x64_3.0.1

# macOS ARM64 (Apple Silicon)
sudo wget -O /opt/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_osx_arm64_3.0.1

# 也可以使用 cURL 下载
sudo curl -L https://github.com/gilbertchen/duplicacy/releases/download/v3.0.1/duplicacy_osx_arm64_3.0.1 -o /opt/duplicacy

# Windows 用户只需这一步即可完成安装
# 不支持 ARM Windows
scoop install duplicacy

赋予可执行权限

sudo chmod +x /opt/duplicacy

创建软链接

sudo ln -s /opt/duplicacy /usr/local/bin/duplicacy

验证安装

Duplicacy 已经安装完成啦,现在您也可以给 duplicacy 命令设置一个简短的别名,编辑 .bashrc.zshrc,添加一行

重载 Shell 配置

# Bash
source ~/.bashrc

# Zsh
source ~/.zshrc

# 适用于所有 Shell
exec $SHELL

以后,您就可以用 dup 命令代替它的全称啦~

使用

本文参考了 Duplicacy Wiki , Duplicacy 社区 的大量说明和帖子,并尽可能保持简单够用的原则,您应该可以在社区根据 标签 快速检索到更多您想要了解的内容。

在开始之前,首先了解下 Duplicacy 的三个基本概念

  • Storage - 目标存储
  • Repository - 存储库
  • Snapshot ID - 快照 ID

Duplicacy Concept

Storage 是 Duplicacy 支持的存储(一般是远程云存储,比如本文中的 OneDrive),我们将多台机器备份到这个存储空间里;Repository 是 Duplicacy 初始化 (init) 一个本地备份目录后形成的 存储库,这一点它和 Git 有一点类似;Snapshot ID 用来区分连接到同一 Storage 的不同 Repository 存储库唯一的 快照 ID

  1. 每一个 Repository 必须有一个独一无二的 Snapshot ID
  2. Snapshot ID 在不同机器上是唯一的
  3. Snapshot ID 只能包含字母、数字、-(连字符) 以及 _(下划线)

为了描述方便,本文接下来保持称呼 Storage, Repository, Snapshot ID

init 初始化

要创建一个用来备份的 Repository,使用 Duplicacy 的 init 命令,查看一下命令帮助1

duplicacy init -h
NAME:
   duplicacy init - 如有必要,初始化存储,并将当前目录初始化为存储库

用法:
   duplicacy init [Options] <Snapshot ID> <Storage URL>

OPTIONS:
   -e  使用密码加密 Storage
   -c <size>  块平均大小 (默认 4M)
   -max <size>  块最大大小 (默认 (块平均大小*4))
   -min <size>  块最大大小 (默认 (块平均大小/4))
   -iterations <i>  存储密钥推导中使用的迭代次数 (默认 16384)
   -pref-dir <path>  .diplicacy 目录的替代位置 (绝对路径或相对路径)
   -storage-name <name>  给 Storage 指定一个名称 (默认 default)
   -repository <path>  在指定的路径而不是当前工作目录下初始化一个新的版本库。
   -key <public key>  用于加密文件块的 RSA 公钥
   -erasure-coding <data shards>:<parity shards>  启用擦除编码以防 Storage 损坏

使用 OneDrive Buisness 作为 Storage 来初始化我们的第一个 Repository,访问应用获取 OneDrive 访问令牌凭据:

授权访问权限后浏览器会自动下载一个 xxx-token.json 文件,将它复制到当前 Repository 的 .duplicacy 目录下

# 初始化 Repository - 需要加密 (OneDrive Personal 的 URL 开头是 one://)
duplicacy init -e cooldog odb://backup
# [出现提示] 输入 xxx-token.json 文件路径
Enter the path of the OneDrive token file (downloadable from https://duplicacy.com/one_start):.duplicacy/odb-token.json
# [出现提示] 输入加密密码
Enter storage password for odb://backup:****************
Re-enter storage password:****************
# [初始化成功] 备份到 Storage 的 backup 目录下,Snapshot ID 为 cooldog
/Users/dejavu/Space/clink will be backed up to odb://backup with id cooldog

现在 OneDrive 的 backup 文件夹会是这样

Backup Folder

本地 Repository 文件目录如下

.
├── .DS_Store
├── .duplicacy  # Duplicacy 配置目录
│   ├── odb-token.json  # OneDrive Business 访问令牌凭据文件
│   └── preferences  # 当前 Repository 配置目录
├── Makefile
├── README.md
├── doc
│   ├── clink.conf
│   ├── clink.nginx
│   └── clink.service
├── index.h
├── main.c
├── mongoose.c
└── mongoose.h

2 directories, 12 files

backup 备份

Repository 正确初始化了,现在就可以尝试同步了,查看命令帮助 2

duplicacy backup -h
NAME:
   duplicacy backup - 将 Repository 的快照保存到 Storage 中

USAGE:
   duplicacy backup [Options]

OPTIONS:
   -hash  通过 Hash 值检测文件差异 (而不是文件大小或时间戳)
   -t <tag>  给备份指定一个标签
   -stats  显示备份过程和备份完成的统计数据
   -threads <n>  上传文件线程数
   -limit-rate <kB/s>  全局上传速度限制 (单位 kb/s)
   -dry-run  空运行测试,实际不备份任何东西。与 -stats 和 -d 一起使用
   -vss  启用影卷复制服务 (仅限 Windows 和使用 APFS 文件系统的 macOS)
   -vss-timeout <timeout>  等待影卷复制操作完成的超时秒数
   -storage <storage name>  备份到指定的 Storage 而不是 default Storage
   -enum-only  递归枚举 Repository 包含或排除的文件和文件夹并退出
   -metadata-chunk-size <size>  元数据块的平均大小 (默认 1M)
   -max-in-memory-entries <number>  保存在 RAM 中的最大条目大小 (默认 1M)

开始备份

duplicacy backup -stats -threads 4
Storage set to odb://backup
Enter storage password:****************
No previous backup found
Listing all chunks
Indexing /Users/dejavu/Space/clink
Parsing filter file /Users/dejavu/Space/clink/.duplicacy/filters
Loaded 0 include/exclude pattern(s)
Uploaded chunk 0 size 104953, 11KB/s 00:00:01 99.8%
Uploaded .DS_Store (6148)
Uploaded Makefile (722)
Uploaded README.md (5102)
Uploaded index.h (2283)
Uploaded main.c (10175)
Uploaded mongoose.c (58270)
Uploaded mongoose.h (21683)
Uploaded doc/clink.conf (142)
Uploaded doc/clink.nginx (220)
Uploaded doc/clink.service (208)
Backup for /Users/dejavu/Space/clink at revision 1 completed
Files: 10 total, 102K bytes; 10 new, 102K bytes
File chunks: 1 total, 102K bytes; 1 new, 102K bytes, 45K bytes uploaded
Metadata chunks: 3 total, 1K bytes; 3 new, 1K bytes, 1K bytes uploaded
All chunks: 4 total, 104K bytes; 4 new, 104K bytes, 47K bytes uploaded
Total running time: 00:00:27

list 罗列

我们使用 list 命令列出有关快照的信息,命令帮助 3

duplicacy list -h
NAME:
   duplicacy list - 列出快照

USAGE:
   duplicacy list [Options]

OPTIONS:
   -all, -a  列出 Repository 中的所有快照
   -id <snapshot id>  列出指定的 Snapshot ID
   -r <revision> [+]  快照的修订编号 (revision)
   -t <tag>  列出具有制定标签的快照
   -files  打印每个快照中的文件列表
   -chunks  打印每个快照中的块,如果没有指定哪个快照,则打印所有块
   -reset-passwords  从输入中获取密码,而不是 Keychain 或 Keyring
   -storage <storage name>  从指定的 Storage 中检索快照
   -key <private key>  解密文件块的 RSA 私钥

可以列出我们现在的 Repository 快照信息

duplicacy list
Storage set to odb://backup
Snapshot cooldog revision 1 created at 2022-12-04 01:55 -hash

列出快照信息的同时打印文件列表 4

duplicacy list -files
Storage set to odb://backup
Snapshot cooldog revision 1 created at 2022-12-04 01:55 -hash
Files: 10
 6148 2022-12-04 01:34:42 6593a90dc7ef81b6e9e81893123649d5398109d9a8986940dad902549045fa49 .DS_Store
  722 2021-09-30 21:30:41 ba93b79806661d3de27563ec5870ea1601eede75757a5c70c24aebaa89f54271 Makefile
 5102 2021-09-30 21:30:41 2143edd665413b6282a4d90993a2465c2e355ce590cdbb4ec58d7d06a89d1f69 README.md
 2283 2021-09-30 21:30:41 588b03a366cedd57c6b541b86b9d0bf90b50a45f7c2654ba69a72ce0105cd4cf index.h
10175 2021-09-30 21:30:41 bf0849dc2d45ec3bb2ed243ad5fbba95c172390c0b0e277588a0a27432377b54 main.c
58270 2021-09-30 21:30:41 a0c55f14ffcef2773d422e6fa80cde9e7ed62c620cc35a76df51d960de3c8918 mongoose.c
21683 2021-09-30 21:30:41 b2b33093437598d63da4b2a3e70ec6f2c17dc248f71567f2ed0f024f49a7afde mongoose.h
  142 2021-09-30 21:30:41 706b0d61343e18c4aeb91435703a0617d308937ab9d7caca516ae0ee9f9e8a2d doc/clink.conf
  220 2021-09-30 21:30:41 667e15beb81904ce08f20c4d9ac92a33c45b2f6e375ccaef15453fe95a17ba68 doc/clink.nginx
  208 2021-09-30 21:30:41 a6e9a1db65655723b2aac6af3a2d4b1e1202c2e69eac55647c93262ab6f1d295 doc/clink.service
Total size: 104953, file chunks: 1, metadata chunks: 3

restore 恢复

restore 用于将 Repository 恢复到之前的修订版 revision,查看命令帮助 5

duplicacy restore -h
NAME:
   duplicacy restore - 将 Repository 恢复到之前保存的快照 (Snapshot)

USAGE:
   duplicacy restore [Options] [--] [Pattern] ...

OPTIONS:
   -r <revision>  快照的修订编号 (必需)
   -hash  通过 Hash 值检测文件差异 (而不是文件大小或时间戳)
   -overwrite  覆盖 Repository 中的现有文件
   -delete  删除不在快照中的文件
   -ignore-owner  不要在恢复的文件上设置原始 UID/GID (用户 ID/用户组 ID)
   -stats  显示恢复过程和完成后的统计数据
   -threads <n>  下载文件的线程数
   -limit-rate <kB/s>  全局下载速度限制 (单位 kb/s)
   -storage <storage name>  恢复到指定的 Storage 而不是 default Storage
   -key <private key>  用于解密文件块的 RSA 私钥
   -persist  即使存在块错误或已经存在的文件,仍然继续处理 (不使用 -overwrite), 并报告任何受影响的文件
   -key-passphrase <private key passphrase>  解密 RSA 私钥的口令 (Passphrase)

Repository 刚才第一次进行 backup 的时候有了第一个 revision,它应该是 1,我对 Repository 里的文件做了一些更改,现在文件目录树如下:

.
├── .DS_Store
├── .duplicacy
│   ├── cache
│   │   └── default
│   ├── odb-token.json
│   └── preferences
├── doc
│   ├── clink.conf
│   ├── clink.nginx
│   └── clink.service
└── index.h

4 directories, 7 files

可以看到,我删除了一些文件,现在我们要恢复到修订编号 (revision) 为 1 的快照

duplicacy restore -r 1 -threads 4 -overwrite -delete -ignore-owner -stats
Storage set to odb://backup
Loaded 0 include/exclude pattern(s)
Indexing /Users/dejavu/Space/clink
Parsing filter file /Users/dejavu/Space/clink/.duplicacy/filters
Loaded 0 include/exclude pattern(s)
Restoring /Users/dejavu/Space/clink to revision 1
Downloaded chunk 1 size 104953, 9KB/s 00:00:01 100.0%
Downloaded Makefile (722)
Downloaded README.md (5102)
Downloaded main.c (10175)
Downloaded mongoose.c (58270)
Downloaded mongoose.h (21683)
Restored /Users/dejavu/Space/clink to revision 1
Files: 6 total, 100K bytes
Downloaded 5 file, 94K bytes, 1 chunks
Skipped 5 file, 9K bytes
Total running time: 00:00:11

现在 Repository 就恢复到 revision 1 了

.
├── .DS_Store
├── .duplicacy
│   ├── cache
│   │   └── default
│   ├── odb-token.json
│   └── preferences
├── Makefile
├── README.md
├── doc
│   ├── clink.conf
│   ├── clink.nginx
│   └── clink.service
├── index.h
├── main.c
├── mongoose.c
└── mongoose.h

4 directories, 12 files

上面这些操作都是在当前计算机上完成的,如果在另一台服务器 6 上执行恢复操作呢?

# 假如这台服务器上也有这个目录
cd backup/clink

# 创建 Duplicacy 配置目录并将 OneDrive 访问令牌凭据文件上传到这个目录下
mkdir .duplicacy

# 初始化 Repository
duplicacy init -e cooldog odb://backup
Enter the path of the OneDrive token file (downloadable from https://duplicacy.com/one_start):.duplicacy/odb-token.json
Enter storage password for odb://backup:****************
The storage 'odb://backup' has already been initialized
Compression level: 100
Average chunk size: 4194304
Maximum chunk size: 16777216
Minimum chunk size: 1048576
Chunk seed: 04f4b3d5140215e00dbd78e619e41fea530a59a2e1f43d49214064e6d8ec01ef
/home/dejavu/backup/clink will be backed up to odb://backup with id cooldog

现在这个 Repository 还是空的

tree -L 3 -a
.
└── .duplicacy
    ├── odb-token.json
    └── preferences

1 directory, 2 files

在这台服务器上恢复修订编号 (revision) 为 1 的快照

duplicacy restore -r 1 -threads 4 -overwrite -delete -ignore-owner -stats
Storage set to odb://backup
Enter storage password:****************
Loaded 0 include/exclude pattern(s)
Indexing /home/dejavu/backup/clink
Parsing filter file /home/dejavu/backup/clink/.duplicacy/filters
Loaded 0 include/exclude pattern(s)
Restoring /home/dejavu/backup/clink to revision 1
Downloaded chunk 1 size 104953, 13KB/s 00:00:01 101.8%
Downloaded .DS_Store (6148)
Downloaded Makefile (722)
Downloaded README.md (5102)
Downloaded index.h (2283)
Downloaded main.c (10175)
Downloaded mongoose.c (58270)
Downloaded mongoose.h (21683)
Downloaded doc/clink.conf (142)
Downloaded doc/clink.nginx (220)
Downloaded doc/clink.service (208)
Restored /home/dejavu/backup/clink to revision 1
Files: 10 total, 102K bytes
Downloaded 10 file, 102K bytes, 1 chunks
Skipped 0 file, 0 bytes
Total running time: 00:00:08

恢复完成

tree -L 3 -a
.
├── doc
│   ├── clink.conf
│   ├── clink.nginx
│   └── clink.service
├── .DS_Store
├── .duplicacy
│   ├── cache
│   │   └── default
│   ├── odb-token.json
│   └── preferences
├── index.h
├── main.c
├── Makefile
├── mongoose.c
├── mongoose.h
└── README.md

4 directories, 12 files

check 验证

check 命令检查指定快照中所有引用的块是否存在 Storage 中,查看命令帮助 7

duplicacy check -h
NAME:
   duplicacy check - 检查快照完整性

USAGE:
   duplicacy check [Options]

OPTIONS:
   -all, -a  检查所有的 Snapshot ID
   -id <snapshot id>  检查指定的 Snapshot ID
   -r <revision> [+]  快照的修订编号 (revision)
   -t <tag>  检查具有制定标签的快照
   -fossils  如果找不到块则从参考 fossils 中检查
   -resurrect  将参考 fossils 转换回块
   -files  验证每个文件的完整性
   -chunks  验证每个块的完整性
   -stats  显示删除重复数据的统计信息 (隐含 -all 参数和所有修订编号)
   -tabular  使用表格式的使用情况和重复数据删除统计信息 (隐含 -stats, -all 参数和所有修订编号)
   -storage <storage name>  从指定的 Storage 中检索快照
   -key <private key>  解密加密文件块的 RSA 私钥
   -key-passphrase <private key passphrase>  解密 RSA 私钥的口令 (Passphrase)
   -threads <n>  验证块的线程数
   -persist  即使存在块错误,仍然继续处理,并报告受影响(损坏)的文件

cat 打印

cat 命令使用标准输出打印文件,查看命令帮助 8

# 查看帮助
duplicacy cat -h

# 查看修订编号 1
duplicacy cat -r 1

history 历史

history 命令显示关于文件 Hash 值、大小、时间戳在修订编号上变化的历史记录 9

# 查看 main.c 的历史记录
duplicacy history -r 1 main.c
Storage set to odb://backup
      1:           10175 2021-09-30 21:30:41 bf0849dc2d45ec3bb2ed243ad5fbba95c172390c0b0e277588a0a27432377b54 main.c
current:            9994 2022-12-04 13:08:50                                                                  main.c*

diff 比较

使用 diff 命令比较两个快照或两个修订版本之间文件的变化

# 比较 main.c 文件在修订编号 1 和 3 之间的变化
duplicacy diff -r 1 -r 3 main.c

# 比较修订编号 1 和 3 之间的变化
duplicacy diff -r 1 -r 3
Storage set to odb://backup
+ 58270 2021-09-30 21:30:41 a0c55f14ffcef2773d422e6fa80cde9e7ed62c620cc35a76df51d960de3c8918 head.c
+ 17705 2022-12-04 12:09:26 65a5308d783eaf2a17b532186b30e10014d08a112404a9d7ab827b425de52e2a head.h
  10175 2021-09-30 21:30:41 bf0849dc2d45ec3bb2ed243ad5fbba95c172390c0b0e277588a0a27432377b54 main.c
*  9994 2022-12-04 13:08:50 f81385aac1c2c805d22eab0cfd52fdcc294cc964cf9df93f704d0255e5ae517e main.c

password 密码

Duplicacy 在备份文件到 Storage 的时候会包含一个 config 文件,这个文件经过加密,password 命令会使用旧的密码揭秘这个文件,并使用新的密码重新加密该文件。修改这个密码 不会 改变用于加密或解密块和快照等文件的加密密钥。

我建议在没有理解这个设计的情况下,您不应当进行任何错误的修改。

duplicacy password -h
NAME:
   duplicacy password - 更改 Storage 的密码

USAGE:
   duplicacy password [Options]

OPTIONS:
   -storage <storage name>  指定特定 Storage 的密码(如果有多个 Storage)
   -iterations <i>  存储密钥推导中使用的迭代次数 (默认 16384)

benchmark 跑分

benchmark 命令运行一组基准测试,包含当前 Repository 使用某种 Storage 的上传/下载速度以及本地硬盘的访问速度。

duplicacy benchmark -h
NAME:
   duplicacy benchmark - 运行一组基准测试下载和上传速度

USAGE:
   duplicacy benchmark [Options]

OPTIONS:
   -file-size <size>  写入/读取的本地文件大小 (单位 MB, 默认值 256)
   -chunk-count <count>  上传/下载的块数量 (默认 64)
   -chunk-size <size>  上传/下载块的大小 (单位 MB, 默认值 4)
   -upload-threads <n>  上传线程的数量 (默认 1)
   -download-threads <n>  下载线程的数量 (默认 1)
   -storage <storage name>  指定 Storage 运行上传/下载基准测试 

这是我的本地访问 OneDrive Business 基准测试(学校的垃圾 Gi-WiFI)

duplicacy benchmark  -upload-threads 2 -download-threads 2
Storage set to odb://backup
Generating 256.00M byte random data in memory
Writing random data to local disk
Wrote 256.00M bytes in 0.08s: 3351.40M/s
Reading the random data from local disk
Read 256.00M bytes in 0.02s: 12587.09M/s
Split 256.00M bytes into 52 chunks without compression/encryption in 1.02s: 251.87M/s
Split 256.00M bytes into 52 chunks with compression but without encryption in 1.26s: 202.83M/s
Split 256.00M bytes into 52 chunks with compression and encryption in 1.29s: 198.21M/s
Generating 64 chunks
Uploaded 256.00M bytes in 253.00s: 1.01M/s
Downloaded 256.00M bytes in 52.00s: 4.92M/s
Deleted 64 temporary files from the storage

这是国内一台小鸡的基准测试,OneDrive 国际版在国内只能说勉强能用

duplicacy benchmark  -upload-threads 2 -download-threads 2
Storage set to odb://backup
Enter the path of the OneDrive token file (downloadable from https://duplicacy.com/one_start):.duplicacy/odb-token.json
Generating 256.00M byte random data in memory
Writing random data to local disk
Wrote 256.00M bytes in 0.21s: 1221.80M/s
Reading the random data from local disk
Read 256.00M bytes in 0.25s: 1012.62M/s
Split 256.00M bytes into 52 chunks without compression/encryption in 1.68s: 152.79M/s
Split 256.00M bytes into 52 chunks with compression but without encryption in 2.30s: 111.39M/s
Split 256.00M bytes into 52 chunks with compression and encryption in 2.37s: 107.92M/s
Generating 64 chunks
Uploaded 256.00M bytes in 273.94s: 957K/s
Downloaded 256.00M bytes in 606.24s: 432K/s
Deleted 64 temporary files from the storage

可以多进行几次基准测试,然后调整块大小、上传/下载线程数量以获得最佳的性能。

set 设置

set 命令用于更改默认或指定 Storage 的选项,选项里有标记 [=true] 的可以用 false 来关闭,比如关闭加密: -e=false ;将密码或访问密钥保存到 Keychain 或 Keyring 中:-no-save-password=false,更多信息可以查看 Duplicacy 的 密码管理

duplicacy set -h
NAME:
   duplicacy set - 更改默认或指定 Storage 的选项

USAGE:
   duplicacy set [Options]

OPTIONS:
   -encrypt, e[=true]  用密码对存储进行加密
   -no-backup[=true]  禁止备份到此 Storage
   -no-restore[=true]  禁止从此 Storage 恢复
   -no-save-password[=true]  不要将密码或访问密钥保存到 Keychain 或 Keyring 中
   -nobackup-file <file name>  包含此名称文件的目录不会被备份
   -exclude-by-attribute[=true]  根据文件属性排除文件 (仅 macOS 有效, 使用 com_apple_backup_excludeItem 处理)
   -key  添加一个密钥/密码,由 -value 选项提供
   -value  密钥/密码的值
   -storage <storage name>
   -filters <file path>  指定包含/排除使用的模式过滤器文件的路径

add 添加

add 命令给当前 Repository 添加一个新的 Storage,大部分选项和 init 初始化类似

duplicacy add -h
NAME:
   duplicacy add - Add an additional storage to be used for the existing repository

USAGE:
   duplicacy add [command options] <storage name> <snapshot id> <storage url>

OPTIONS:
   -e  使用密码加密 Storage
   -c <size>  块平均大小 (默认 4M)
   -max <size>  块最大大小 (默认 (块平均大小*4))
   -min <size>  块最大大小 (默认 (块平均大小/4))
   -iterations <i>  存储密钥推导中使用的迭代次数 (默认 16384)
   -copy <storage name>  使新 Storage 与现有 Storage 兼容,以进行复制操作
   -bit-identical  (当使用 -copy 的时候) 使新的 Storage 相同,也允许 rsync 等
   -repository <path>  在指定的路径而不是当前工作目录下初始化一个新的版本库。
   -key <public key>  用于加密文件块的 RSA 公钥
   -erasure-coding <data shards>:<parity shards>  启用擦除编码以防 Storage 损坏

需要注意的是 -bit-identical 不能直接将 config 文件从未加密的 Storage 复制到新的加密 Storage。

copy 复制

copy 命令用于将快照从一个 Storage 复制到另一个 Storage,这两个 Storage 想要兼容复制,需要满足条件:一些配置参数必须相同,其中一个 Storage 在使用 add 命令添加的时候必须附加 -copy 选项进行初始化。查看命令帮助10

duplicacy copy -h
NAME:
   duplicacy copy - 在兼容的 Storage 之间复制快照
USAGE:
   duplicacy copy [Options]

OPTIONS:
   -id <snapshot id>  指定 Snapshot ID 复制,而不是复制所有快照
   -r <revision> [+]  指定修订编号
   -from <storage name>  快照被复制的源 Storage
   -to <storage name>  快照复制到的目标 Storage
   -download-limit-rate <kB/s>  全局下载速度限制 (单位 kb/s)
   -upload-limit-rate <kB/s>	  全局上传速度限制 (单位 kb/s)
   -threads <n>  上传线程数
   -download-threads <n>  下载线程数
   -key <private key>  解密快照被复制的源 Storage 的 RSA 私钥
   -key-passphrase <private key passphrase>  解密 RSA 私钥的口令 (Passphrase)

prune 修剪

随着时间的推移,Storage 的空间占用越来越大,一般我们只需要保留一定「保留策略」的快照(比如七天、一个月、半年……),prune 命令用于在 Storage 中删除快照中过旧的或者不再需要的修订版本及未使用的块。

duplicacy prune -h
NAME:
   duplicacy prune - 根据修订编号、标签和保留策略修剪快照

USAGE:
   duplicacy prune [command options]

OPTIONS:
   -id <snapshot id>  删除指定 Snapshot ID 的快照而不是默认快照
   -all, -a  匹配所有 Snapshot ID
   -r <revision> [+]  删除指定的修订编号
   -t <tag> [+]  删除带有指定标签的快照
   -keep <n:m> [+]  对于超过 m 天的快照,保留每 n 天一个快照
   -exhaustive  删除所有未引用的块 (不仅仅是被删除的快照引用的块)
   -exclusive  假设对 Storage 的独占访问 (禁止另外收集 fossil)
   -dry-run, -d  显示哪些内容会被删除
   -delete-only  删除之前收集的 fossil (如果可删除) 且不收集 fossil
   -collect-only  识别和收集 fossil 且不删除以前收集的 fossil
   -ignore <id> [+]  在决定是否可以删除 fossil 时忽略制定的 Snapshot ID 的快照
   -storage <storage name>  修剪指定 Storage 的快照
   -threads <n>  修剪未引用块的线程数

比如:

# 对于超过 30 天的修订,每 7 天保留一次修订
duplicacy prune -keep 7:30 

# 删除超过一年的备份
duplicacy prune -keep 0:365

# 指定多个 -keep 保留策略,按照 m 的降序排列
duplicacy prune -keep 0:360 -keep 30:180 -keep 7:30 -keep 1:7

一般地,假如多个 Repository 备份到同一个 Storage,建议只有一个 Duplicacy 实例运行 prune 修剪策略

需要卸载?

# 取消软链接
sudo rm -i /usr/local/bin/duplicacy

# 删除程序
sudo rm /opt/duplicacy

# Windows
scoop uninstall duplicacy

免费存储

在不付费的情况下可以白嫖的存储服务推荐(Duplicacy 支持使用的服务),对于重要的服务应当优先考虑稳定性。

服务名称免费层说明
Cloudflare R210GB 存储,下行流量免费A 类操作 100 万;B 类操作 1000 万;兼容 S3 API;需要绑定支付方式
OneDrive E5 Developer5TB~25TB 存储,完全免费国内机器连接慢,极少账号会翻车
OneDrive Personal5GB 存储,完全免费国内机器连接慢,账号稳定
Backblaze B210GB 存储,1GB 下行流量兼容 S3 API;Duplicacy 本身支持
Oracle Object Storage20GB 存储,10TB 下行流量兼容 S3 API;
阿里云 OOS5GB 存储,5GB 下行流量仅限香港区域,兼容 S3 API
Dropbox2GB 存储,完全免费国内被墙
FileBase5GB 存储,完全免费IPFS 区块链存储,兼容 S3 API
Scaleway75GB 存储,75GB 下行流量兼容 S3 API
Google Drive15GB 存储,完全免费Duplicacy 本身支持
Synology C215GB 存储,15GB 下行流量兼容 S3 API
Storj DCS150GB 存储,150GB 下行流量兼容 S3 API
IDrive E210GB 存储,完全免费兼容 S3 API(此外:首年 1TB/$4.00)
Tebi.io25GB 存储,250GB 下行流量兼容 S3 API
Getspace50GB 存储,完全免费支持 WebDAV,速度还行

上面这些免费存储,有些比较稳定,有些免费且大碗,可酌情选择。