登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux tar 排除规则与目录层级的打包

来源:17golang原创

时间:2026-10-28 13:27:26 434浏览 收藏

Linux tar 的排除规则要与归档中的成员名称对应。先用 -C 明确从哪里选文件、是否保留顶层目录,再把排除选项放在待打包对象之前。通配符使用引号交给 tar 处理,输出归档放到源目录之外,可以减少层级错位和归档包含自身的问题。

本文采用 GNU tar。把“源目录在哪里”“归档里叫什么”“排除哪些成员”分开决定,规则才便于迁移和复用。

GNU tar 官方手册地址:https://www.gnu.org/software/tar/manual/tar.html

把成员命名当成打包接口

假设项目位于 /srv/demo-app,包含 src、cache、build 和 notes。交付时希望保留 demo-app 这一层,但不要根级 cache 和 build。这个要求描述的是归档布局,不只是把某个磁盘目录压缩起来。

使用 -C /srv 后选择 demo-app,成员会以 demo-app 为顶层;改成 -C /srv/demo-app 后选择点号,成员通常以 ./ 开头,两种方式需要对应的排除前缀。不能更改打包入口后,仍机械沿用旧规则。

源目录、工作目录与归档成员布局关系
静态结构图:-C 影响后续输入名称的解释,输入对象决定是否保留 demo-app 顶层目录。

用固定前缀写出一条完整命令

下面命令假设 /srv/demo-app 已存在,/var/tmp 可写,并且目标归档文件名尚未使用。它保留项目顶层目录,只排除该顶层下的 cache 与 build。示例命令未在本文生成环境执行,不提供伪造的运行输出。

# 确认使用的实现;本文选项以 GNU tar 为准。
tar --version

# 规则先于输入对象,输出归档独立于源目录。
tar -czf /var/tmp/demo-app-release.tar.gz \
  --anchored \
  --exclude='demo-app/cache' \
  --exclude='demo-app/build' \
  -C /srv demo-app

-c 创建归档,-z 使用 gzip,-f 后紧跟输出文件名。-C /srv 表示把后续输入 demo-app 解释为该目录下的对象,而不是把 /srv 这个绝对路径层级一起保存进去。使用绝对输出路径也让命令从不同工作目录调用时更容易理解。

--anchored 将这些排除模式限制在名称开头的目录组件序列。排除一个目录本身,在正常递归打包时也排除了其中内容;本例不需要再补一个 cache/*。不要随手给模式末尾加斜杠,GNU tar 不会在匹配前自动删掉规则里的末尾斜杠。

如果交付方要求归档直接展开 src、notes 等内容,而不要 demo-app 外层,可以使用另一套命名约定:

# 输入改为点号时,规则同步改成 ./ 前缀。
tar -czf /var/tmp/demo-app-contents.tar.gz \
  --anchored \
  --exclude='./cache' \
  --exclude='./build' \
  -C /srv/demo-app .

这两条命令是两种布局选择,按交付需要选择一种即可,不是必须依次执行的操作。后者的点号输入也覆盖隐藏条目,不需要用 shell 的星号去枚举整个目录。

同名目录与通配符不能靠猜

GNU tar 的排除模式默认不锚定开头,因此只写 cache 可能匹配更深层的同名目录。本例明确写出 demo-app/cache 并开启 anchored,是为了保留例如 demo-app/src/cache 这类不同业务目录,避免一个短词误伤多个位置。

如果需求本来就是排除任意层级的某类文件,则可以明确采用相应模式。比如下面按后缀排除所有 .tmp 文件;这是独立配方,不继承前文命令的 anchored 设置。

# 引号阻止 shell 提前展开通配符,由 tar 匹配源树中的名称。
tar -czf /var/tmp/demo-app-no-temp.tar.gz \
  --exclude='*.tmp' \
  -C /srv demo-app

排除模式中的星号默认可以跨越斜杠;需要单层匹配时,应显式选择相应的匹配选项。不要把它当成正则表达式,也不要直接照搬 .gitignore 的否定规则。一个命令里重复设置匹配选项时,它们对后续规则的作用也需要保持清楚。

输入成员、排除模式和最终归档集合关系
静态说明图:成员命名和匹配配置共同限定排除集合,输出归档位于源树之外。

规则较多时保存独立清单

排除项增加后,可以把模式放进源目录外的文件,每行一项。例如 /var/tmp/demo-app.exclude 的内容为:

demo-app/cache
demo-app/build

这是原始模式清单,不是 shell 脚本,不在每行添加命令引号或注释。这里两行均按保留 demo-app 顶层的布局书写。文本编辑器若带入行尾空格,可能使规则与预期名称不同,因此清单应保持纯粹。

# -X 读取逐行模式,仍保持规则在输入对象之前。
tar -czf /var/tmp/demo-app-from-list.tar.gz \
  --anchored \
  -X /var/tmp/demo-app.exclude \
  -C /srv demo-app

将模式文件放在源目录外,也避免把规则文件本身顺带交付。若从其他路径调用,给 -X 使用绝对路径可以减少歧义。-C 主要改变后续输入文件名的基准,不应依赖它自动为所有选项参数重写路径。

判断这个归档是否适合交付

读者在自己的测试目录执行命令后,可以列出归档成员判断层级。检查应包含应当保留的文件,而不只是确认被排除的目录看不见;否则“什么都没打进去”也可能被误当成排除成功。

# 只列出归档名称,不向当前目录解包。
tar -tzf /var/tmp/demo-app-release.tar.gz
判断点本例要求不满足时先看哪里
顶层布局保留 demo-app-C 后选择的是目录名还是点号
排除范围根级 cache、build 不进入归档规则前缀、anchored 与参数位置
保留内容src 等交付内容存在是否用过宽的目录短名称
归档位置源目录之外-f 参数与输出路径

这种模式适合制作源码包或约定明确的文件交付物。它并不提供活跃数据库的一致性快照,也不能让打包过程中持续变化的文件自动保持同一时间点。遇到读取错误、权限错误或文件变化提示,应结合退出状态处理,而不是只看是否生成了 tar.gz 文件。

为什么排除参数写在最后没有效果?

GNU tar 创建归档时,排除等选项具有位置敏感性,应放在受影响的输入对象前面。优先整理命令结构,不要先增加更多同义规则。

排除目录要写末尾斜杠吗?

本例不写。按实际成员名称匹配目录即可,不应把其他工具的规则格式直接搬进来。

这套写法适用于所有 tar 吗?

本文只承诺 GNU tar 的规则。BSD tar、BusyBox tar 及不同发行版附带实现的可选参数可能不同,迁移脚本前应以目标实现的帮助和手册为依据。

官方资料:位置敏感选项、模式匹配范围、GNU tar 完整手册。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>