Files
BakNRet/docs/backup-list-syntax.md
T
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

5.9 KiB
Raw Blame History

BackupList.txt 语法

本文从 README.md 拆出,单独成篇是为了让它能被单独引用与单独评审。

[+|-] <软件名 或 绝对路径> [ :: <绝对路径> ] [ :- <模式>[,<模式>...] ] [ :+ <追加项>[,<追加项>...] ]
                            [ :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= 已废弃,只会打印告警)。

# 软件名:用名录里的 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 介绍一起打印:

Edge :- !*Cache,!Crashpad  # 缓存与崩溃转储都可再生,不进归档

# 必须前面有空白才算注释,所以路径里的 C:\a#b 不受影响。

运行时会把每个条目的归档项逐条介绍出来

说明来自 SoftwareCatalog.psd1 的 Slot,追加/排除的来源来自清单:

[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",不再是 :- 的历史别名;排除一律写 :-。