tar 增量归档排除缓存目录的参数组合
要让 GNU tar 做增量归档并排除缓存目录,最稳妥的组合是:用 --listed-incremental=状态文件 持久记录变化,用 --exclude-from=规则文件 排除按名称确定的缓存路径,再用 --exclude-caches-all 补充排除带有效 CACHEDIR.TAG 的缓存目录。状态文件和归档文件都应放在源目录之外。
第一次使用一个不存在的快照文件时会形成完整基线;以后复用同一个快照文件,tar 会更新其中的文件系统状态并生成后续增量。排除规则也要在同一条归档链中保持稳定,否则应开启新的 level-0 基线。
官方地址:https://www.gnu.org/software/tar/manual/html_node/Incremental-Dumps.html
-g app.snar保存增量状态,不能把它当作可丢弃的临时文件。-X app.exclude读取一行一个的排除模式,适合维护多条缓存路径。--exclude-caches-all只识别带有效 CACHEDIR.TAG 的目录,不按目录名称猜测。
先用最小参数组合完成一次归档
下面的命令固定源目录为 /srv/app,把成员名保存为相对路径,同时把归档与 .snar 状态文件放到源目录之外。--one-file-system 是可选保护项,用于避免递归跨入挂载在源树下的其他文件系统。
#!/usr/bin/env bash set -eu SOURCE='/srv/app' ARCHIVE_DIR='/srv/backup' STATE_DIR='/var/lib/tar-snapshots' EXCLUDES='/etc/backup/app.exclude' # 快照文件必须跨轮次保留;归档名则要保证每次唯一。 SNAPSHOT="$STATE_DIR/app.snar" ARCHIVE="$ARCHIVE_DIR/app-$(date +%F-%H%M%S).tar.gz" mkdir -p "$ARCHIVE_DIR" "$STATE_DIR" tar --create --gzip \ --file="$ARCHIVE" \ --listed-incremental="$SNAPSHOT" \ --exclude-from="$EXCLUDES" \ --exclude-caches-all \ --one-file-system \ --directory="$SOURCE" . # 以源目录为归档根,避免写入绝对路径。
--listed-incremental 的参数是 tar 的快照状态文件,不是输出归档。官方文档说明,它用于判断自上次备份以来新增、修改或删除的文件;执行创建操作后,该文件会被更新。不要把它放进待归档目录,也不要让清理脚本删除它。

把名称规则放进独立排除文件
规则少时可以重复写多个 --exclude='模式';规则多时用 --exclude-from 更清楚。GNU tar 的排除项使用 shell glob,不是正则表达式。写在命令行的通配符必须加引号,避免先被 shell 展开;写在文件中则一行一个模式,以 # 开头的行可以作为注释。
# 排除归档根目录下的缓存目录。 ./.cache ./tmp/cache # 排除任意子目录中的同名缓存目录。 */.cache */tmp/cache # 这些目录可由依赖安装或构建过程重新生成。 */node_modules/.cache */var/cache
是否要写得更宽取决于数据语义。不要仅因为目录名包含 cache 就使用 *cache*,它可能误排业务目录或文件。优先列出已经确认可重建的目录;排除一个目录节点时,其下内容也不会进入归档。
区分名称排除与缓存标签排除
--exclude-caches-all 并不是“排除所有名字叫 cache 的目录”。它查找的是有效的 CACHEDIR.TAG 文件。GNU tar 提供三种标签语义:--exclude-caches 保留目录节点和标签文件;--exclude-caches-under 只保留目录节点;--exclude-caches-all 连该目录节点也不归档。
| 需求 | 参数 | 归档结果 |
|---|---|---|
| 排除确定名称的 .cache | --exclude 或 --exclude-from | 匹配目录及内容不进入归档 |
| 保留标签,排除标签目录内容 | --exclude-caches | 保留目录节点与 CACHEDIR.TAG |
| 只保留标签目录节点 | --exclude-caches-under | 不保留标签文件和内容 |
| 整个标签目录都省略 | --exclude-caches-all | 目录节点也不进入归档 |
名称规则和标签规则可以同时使用:前者覆盖团队明确知道的缓存路径,后者尊重应用写入的标准缓存标签。这样不会把“目录名字”和“目录内容可重建”混为一谈。

固定快照文件与归档根路径
一条增量链必须能找到同一个快照状态。首次运行若状态文件不存在,GNU tar 会创建它并形成基线;后续运行复用它,状态会继续推进。要强制开启新的完整基线,可以使用一个新的快照文件,或在 --listed-incremental 同时使用 --level=0。
# 排除策略或源目录边界变化时,开始新的 level-0 归档链。 tar --create --gzip \ --file='/srv/backup/app-full.tar.gz' \ --listed-incremental='/var/lib/tar-snapshots/app.snar' \ --level=0 \ --exclude-from='/etc/backup/app.exclude' \ --exclude-caches-all \ --directory='/srv/app' .
-C/--directory 也应固定。今天从 /srv 归档 app,明天却从 /srv/app 归档 .,成员名称边界会改变,不利于理解和恢复。把源根、排除文件、状态文件命名和归档链编号一起纳入备份配置。
检查成员并按顺序恢复
创建后先列出归档。对增量归档,GNU tar 可以在列表模式下结合 --incremental 和两次 --verbose 展示目录元数据;普通成员列表则适合快速搜索是否仍有 .cache 路径。
# 查看增量归档中的目录状态与成员信息。 tar --list --incremental --verbose --verbose \ --file='/srv/backup/app-2026-10-01-210000.tar.gz' # 快速检查成员名;有匹配项时需要回看排除模式。 tar --list --file='/srv/backup/app-2026-10-01-210000.tar.gz' \ | grep -E '(^|/)\.cache(/|$)' || true
恢复时必须从完整基线开始,再按生成顺序应用每个增量归档。官方文档提醒,增量恢复会尝试还原创建归档时的精确目录状态,可能删除当时已不存在的文件。因此先恢复到空的暂存目录,不要把第一次演练直接指向生产目录。
# 使用空目录演练;依次应用完整归档和后续增量归档。 mkdir -p '/srv/restore-test' tar --extract --listed-incremental=/dev/null \ --file='/srv/backup/app-full.tar.gz' --directory='/srv/restore-test' tar --extract --listed-incremental=/dev/null \ --file='/srv/backup/app-inc-01.tar.gz' --directory='/srv/restore-test'
完整参数速查
| 参数 | 作用 | 常见错误 |
|---|---|---|
| --listed-incremental=FILE | 读取并更新增量快照状态 | 每次换一个文件,导致每次都像新基线 |
| --exclude=PATTERN | 排除单个命令行模式 | 没有引号,通配符被 shell 提前展开 |
| --exclude-from=FILE | 从文件读取多条模式 | 把 FILE 本身误当成要排除的路径 |
| --exclude-caches-all | 省略带有效缓存标签的整个目录 | 误以为会按 cache 目录名自动识别 |
| --directory=DIR | 切换归档根目录 | 不同轮次改变根路径与成员名称 |
| --level=0 | 强制建立新的完整基线 | 在日常增量轮次误用,增加归档体积 |
常见问题
只写 --exclude-caches-all 就能排除 .cache 吗?
不能保证。只有目录中存在有效 CACHEDIR.TAG 时才会触发标签排除;确定名称的目录仍应放入 --exclude 或 --exclude-from 规则。
可以删除 .snar 后继续做增量吗?
删除后会失去前一轮状态,下一次将重新形成完整基线。快照文件应与归档链一起管理,但不等同于归档数据本身。
修改排除文件后能直接沿用旧链吗?
命令可以运行,但恢复语义会更难判断。运维上更稳妥的做法是把排除策略版本化,并在策略边界变化时开启新的 level-0 链。
表盘自定义工具重复安装会顶替旧表盘吗?自定义表盘 ID 与恢复说明
- 上一篇
- 表盘自定义工具重复安装会顶替旧表盘吗?自定义表盘 ID 与恢复说明
- 下一篇
- Go cgo.Handle 管理 Go 值跨语言传递
-
- 文章 · linux | 2天前 | Linux · 运维 · 日志排查 · journalctl 启动日志 Boot ID --list-boots systemd日志导出
- journalctl 按启动会话筛选并导出日志
- 369浏览 收藏
-
- 文章 · linux | 2天前 | Linux · Linux防火墙 nftables verdict map 多端口策略
- nftables verdict map 组织多端口策略的规则设计
- 475浏览 收藏
-
- 文章 · linux | 3天前 | 权限控制 · 服务管理 · systemd socket激活 systemd.socket ListenStream Accept
- systemd socket 激活服务的依赖与监听配置
- 229浏览 收藏
-
- 文章 · linux | 3天前 |
- Linux ip rule 怎么按来源地址选择路由表
- 347浏览 收藏
-
- 文章 · linux | 3天前 | Linux · 文件系统 · Linux mount bind mount remount
- Linux bind mount 怎么二次挂载为只读
- 116浏览 收藏
-
- 文章 · linux | 4天前 |
- systemd-sysusers 怎么声明软件包所需系统账号
- 150浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 290次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 342次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 344次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 308次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 130次使用
-
- 详解golang执行Linuxshell命令完整场景下的使用方法
- 2023-01-07 426浏览
-
- go程序部署到linux上运行的实现方法
- 2023-01-02 387浏览
-
- Linux系统下Go语言开发环境搭建
- 2023-01-07 242浏览
-
- 使用golang获取linux上文件的访问/创建/修改时间
- 2022-12-31 238浏览
-
- 在Linux系统中安装Go语言的详细教程
- 2022-12-29 402浏览
