Files
BakNRet/docs/backup-list-syntax.md
Shuery 60ecbc2933 docs: README 拆出四篇主题文档,本文件留总览与操作
拆出软件名录(67 行)、清单语法(114 行)、归档布局与迁移(47 行)、安全描述符(69 行),共 297 行;README 从 653 降到 360 行,每节原位留一句摘要加链接。

为什么拆:这四块是「要查的资料」,README 剩下的是「要读的流程」。混在一起时,想查清单语法的人得先滚过一百多行总览;拆开后每篇也能被单独引用与单独评审。

搬运按标题抽取原文、不重打,并在写之前断言正文长度、写之后再读回断言一次(第一次尝试就是栽在没有断言上:@(a, b, $arr) 不会展开数组,而是把 $arr 拼成一行,结果四篇各只有 5 行、正文却已从 README 删除。那次已回滚)。
2026-09-27 10:20:08 +08:00

119 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BackupList.txt 语法
> 本文从 [README.md](../README.md) 拆出,单独成篇是为了让它能被单独引用与单独评审。
```text
[+|-] <软件名 或 绝对路径> [ :: <绝对路径> ] [ :- <模式>[,<模式>...] ] [ :+ <追加项>[,<追加项>...] ]
[ :encrypt | :!encrypt ] [ @ <Key>='<值>' ] [ # 说明 ]
```
修饰符必须是**独立的、前后带空白的记号**,所以路径里出现的 `:-`、`C:\a#b` 之类不会被误切。
### 目标(二选一)
| 写法 | 说明 |
| --- | --- |
| `Edge` | **软件名**:去 `SoftwareCatalog.psd1` 查 Slot 组,**归档名 = 软件名** |
| `C:\Programs\MiFlash` | **手写路径**:含 `\` `/` 或 `%` 就按路径处理,归档名 = `<末级名>_from_<上级路径用 + 连接>` |
| `Edge @pathname` | 软件名 + 强制用路径命名(想换到名录体系但暂时不想改归档名时用) |
### 行首方向标记
| 标记 | 作用 |
| --- | --- |
| `+` | **仅备份,不恢复**(`Restore.ps1` 会跳过它;归档名照旧算"有主"的,不会被报成孤儿) |
| `-` | **仅恢复,不备份**(`Backup.ps1` 会跳过它;适合放在别处、必要时才还原的目录) |
| 无 | 既能备份也能恢复(默认) |
### 修饰符
| 修饰符 | 等价写法 | 作用 |
| --- | --- | --- |
| `:: <绝对路径>` | `@ Path='<绝对路径>'` | 覆盖 Path(软件名条目只有一个 Slot 时可用) |
| `:- <模式>[,...]` | `@ Exclude='<模式>'` | 排除模式(`,` `;` 都当分隔符),**覆盖**名录里各 Slot 的 Exclude |
| `:+ <追加项>[,...]` | `@ Include='<追加项>'` | 追加项,语法 `<归档内相对路径>:<宿主机绝对路径>`,**覆盖**名录里的 Include |
| `:encrypt` | `@ Encrypt='$true'` | 该条目加密 |
| `:!encrypt` | `@ Encrypt='$false'` | 该条目不加密 |
| `@ <Key>='<值>'` | — | 覆盖名录里的默认字段(目前支持 Path / Exclude / Include / Encrypt) |
兼容的历史写法仍然认:`@encrypt` / `@!encrypt` / `@pathname` / `@root=<名>`(`root=` 已废弃,只会打印告警)。
```text
# 软件名:用名录里的 Slot 与排除;再把额外目录放进包内 Modules\ 位置
Scoop :- GlobalPersist\steam\steamapps
# 手写目录 + 排除
C:\Programs\MiFlash :- MiFlash\logs\
# 追加映射:把宿主机的 D:\extra\ps-modules 放到包内 Modules\ 下
PowerShell :+ Modules:D:\extra\ps-modules
# 覆盖加密(名录里默认加密时特别有用)
PowerShell @ Encrypt='$false'
WindowsPowerShell :!encrypt
```
### 模式(排除 / 追加)怎么写
模式匹配的是**归档内的相对路径**,而且**相对本 Slot 的根**(也就是 `<Slot>\` 里面那一层):
| 形态 | 展开成 | 说明 |
| --- | --- | --- |
| `<相对路径>` | `-x!<Slot>\<相对路径>` | 锚定在归档根下这一份 |
| `!<通配>` | `-xr!<通配>` | **任意层级**按组件名匹配,`*` `?` 是 7z 通配符(不是正则) |
| `!re:<正则>` | 若干 `-x!<完整路径>` | **正则**:脚本自己遍历源目录把命中的路径展开成精确排除项 |
| `GlobalPersist\steam` | `-x!GlobalPersist\steam` | 第一段是 Slot 名时,只作用在那一个 Slot 上 |
- `!*Cache` 一次覆盖 `Cache` / `Code Cache` / `GPUCache` / `DaemonCache` 等一批以 Cache 结尾的组件名。
- 模式里**不要自己写引号**;模式里的空格会被自动转成 `?`(7z 的 `-x!` 不接受带空格的模式)。
- 想把 `.log` 之类按正则排除就写 `!re:.*\.log$`;命中的目录会整棵剪掉,命中数超过 300 条会明确报错
(命令行长度有限),这时应该改用更粗的通配模式。
- 不带 `!` 的模式是**锚定**的:Edge 的 `OneAuth\WebView2\EBWebView\` 里还有一整套自己的
`Crashpad` / `BrowserMetrics` / `ProvenanceData` / `optimization_guide`,锚定模式碰不到它们,
这些可再生的东西一律用 `!<组件名>` 才会在任意层级命中。
实测效果(本机真实 Edge 配置,源 4619.9 MB):
| Edge 归档 | 大小 | 条目数 |
| --- | --- | --- |
| 排除规则生效前 | 1781 MB | 27961 |
| 排除规则生效后 | 72 MB | 2294 |
书签、密码(`Login Data`)、`Cookies`、偏好、历史、`IndexedDB`、`Local Storage` 全部保留;
缓存、组件缓存、Service Worker、扩展本体、遥测与优化数据全部排除。
### 行尾可以写"为什么"
行尾的 ` # 说明` 会被解析出来,运行时和 Slot 介绍一起打印:
```text
Edge :- !*Cache,!Crashpad # 缓存与崩溃转储都可再生,不进归档
```
`#` 必须前面有空白才算注释,所以路径里的 `C:\a#b` 不受影响。
### 运行时会把每个条目的归档项逐条介绍出来
说明来自 `SoftwareCatalog.psd1` 的 Slot,追加/排除的**来源**来自清单:
```text
[INFO] 条目:Scoop
[INFO] 归档:Scoop.7z;方向:备份 + 恢复;加密:是
[INFO] 归档项 1/3:DefaultConfig <- C:\Users\Shuery\.config\scoop
[INFO] 来源:软件名录;存在,会打包;目录
[INFO] 介绍:Scoop 配置。
[INFO] 归档项 2/3:GlobalPersist <- C:\ProgramData\scoop\persist
[INFO] 来源:软件名录;存在,会打包;目录
[INFO] 排除 1 条(来自清单的 :- / @ Exclude):GlobalPersist\steam\steamapps
[INFO] 排除 2 条(来自 BackupConfig.psd1 的 DefaultExcludes):!Thumbs.db、!desktop.ini
```
`Restore.ps1` 也会打印"哪一项还原到哪个目录、是文件还是目录、会新建还是覆盖"。
### 几个必须知道的约束
- **归档名重复会直接报错。** 归档名 = 软件名字,所以同一个软件写两遍会让两个条目互相覆盖。
- **同一软件里的 Slot 名不能重复**,追加项的归档内路径也不能和 Slot 撞;脚本会在打包前明确报错。
- **一个条目挂多个归档项时,每一项只还原自己那棵子树**,不会把兄弟项也复制到别的父目录下。
- **`::` 现在是"覆盖 Path"**,不再是 `:-` 的历史别名;排除一律写 `:-`。