You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI/CD创建tar.gz排除自身,解决文件读取变更报错

解决tar打包时排除自身归档文件的问题

问题场景

在当前工作目录(例如/builds/project/)创建archive.tar.gz归档文件,需要确保该归档文件本身不会被打包进去。尝试使用--exclude=PATTERN选项但未成功,最终希望通过变量指定归档文件名并实现排除。

版本信息

$ bash --version
GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ tar --version
tar (GNU tar) 1.34
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by John Gilmore and Jay Fenlason.

尝试过的无效命令及错误

# 选项顺序错误导致归档文件名识别失败
$ tar -czf --exclude=archive1.tar.gz archive1.tar.gz . || true
tar: archive1.tar.gz: Cannot stat: No such file or directory
tar: .: file changed as we read it
tar: Exiting with failure status due to previous errors

$ tar -czf --exclude="archive2.tar.gz" archive2.tar.gz . || true
tar: archive2.tar.gz: Cannot stat: No such file or directory
tar: .: file changed as we read it
tar: Exiting with failure status due to previous errors

$ tar -czf --exclude=./archive3.tar.gz archive3.tar.gz . || true
tar: archive3.tar.gz: Cannot stat: No such file or directory
tar (child): --exclude=./archive3.tar.gz: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: --exclude=./archive3.tar.gz: Cannot write: Broken pipe
tar: Child returned status 2
tar: Error is not recoverable: exiting now

# 选项顺序正确但相对路径排除失效
$ tar -czf archive5.tar.gz --exclude=archive5.tar.gz . || true
tar: .: file changed as we read it

$ TAR_FILE=archive13.tar.gz ; tar -czf $TAR_FILE --exclude=$TAR_FILE . || true
tar: .: file changed as we read it

有效解决方案

方法1:使用绝对路径排除

用绝对路径精准匹配要排除的归档文件,避免相对路径的匹配歧义:

TAR_FILE="archive.tar.gz"
tar -czf "$TAR_FILE" --exclude="$(pwd)/$TAR_FILE" .

原理:tar遍历当前目录时,文件路径以相对形式存在,而$(pwd)/$TAR_FILE是归档文件的绝对路径,能准确匹配到正在创建的文件,从而实现排除。

方法2:提前创建空归档文件再排除

先创建空的归档文件,让tar在遍历目录时能识别到该文件并排除:

TAR_FILE="archive.tar.gz"
touch "$TAR_FILE"
tar -czf "$TAR_FILE" --exclude="$TAR_FILE" .

原理:提前创建文件后,tar遍历目录时会找到该文件并应用排除规则,后续tar写入归档内容时不会将自身打包进去。

方法3:将归档文件放在当前目录外

直接把归档文件创建到当前目录的上级目录,从根源避免需要排除的问题:

TAR_FILE="../archive.tar.gz"
tar -czf "$TAR_FILE" .

失败原因分析

  1. 选项顺序错误:前几个命令将--exclude放在-czf之后紧跟,而-f选项要求后面必须直接跟归档文件名,导致tar误将--exclude=...当作归档文件名,引发报错。
  2. 相对路径匹配问题:当使用相对路径排除时,tar在创建归档文件的过程中,文件处于动态生成状态,tar遍历到当前目录时,归档文件可能还未完全生成,或者相对路径的匹配逻辑无法识别正在写入的文件,导致排除规则失效。

内容的提问来源于stack exchange,提问作者rosaLux161

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:32:08