tar本身只打包不压缩,-z、-j、-j参数才调用gzip、bzip2、xz进行压缩;绝对路径打包会导致解压出现./前缀,应使用-c切换目录或避免以/开头;解压前需确保目标目录存在。

tar 命令本身不压缩,只打包;真正压缩靠 -z(gzip)、-j(bzip2)或 -J(xz)。直接用 tar -cf 得到的是未压缩的 .tar 文件,体积几乎不变。
压缩目录时多出一层 ./ 的问题
常见现象:执行 tar -czvf archive.tar.gz /path/to/dir 后解压,发现里面是 ./dir/...,而不是期望的 dir/...。这是因为 /path/to/dir 是绝对路径,tar 会保留路径结构。
解决办法是切换到父目录再操作:
- 用
-C切工作目录:tar -C /path/to -czvf archive.tar.gz dir - 或先
cd /path/to && tar -czvf /tmp/archive.tar.gz dir - 避免用绝对路径作为源参数,尤其不要以
/开头
否则上传部署时,程序读取相对路径(如 config.yml)会失败——它实际在 ./dir/config.yml,而非当前目录下。
tar -czvf 和 tar -cjvf 的实际差异
-z(gzip)快、兼容性好,适合日常传输;-j(bzip2)压缩率更高(通常小 10–20%),但耗 CPU 多、速度慢,老系统可能没装 bzip2 工具。
实测一个 500MB 日志目录:
-
tar -czvf log.tar.gz logs/:耗时约 8 秒,结果 120MB -
tar -cjvf log.tar.bz2 logs/:耗时约 22 秒,结果 95MB
如果目标机器是嵌入式设备或 CI 构建机,优先选 -z;若存档长期保存且磁盘紧张,可选 -j 或更省空间的 -J(xz,需确认系统有 xz)。
解压时目标目录不存在导致失败
tar -xzvf file.tar.gz -C /target/dir 要求 /target/dir 必须已存在,tar 不会自动创建它(哪怕加了 -v 也报错:tar: /target/dir: Cannot open: No such file or directory)。
安全做法是提前创建:
mkdir -p /target/dir && tar -xzvf file.tar.gz -C /target/dir- 或用子 shell 避免污染当前环境:
(mkdir -p /target/dir && tar -xzvf file.tar.gz -C /target/dir)
别依赖 -C 自动建目录——这是常见疏忽,尤其写成自动化脚本时容易漏掉判断。
排除不需要的文件再压缩
比如打包代码但想跳过 node_modules、.git 或临时日志:
- 单个排除:
tar -czvf app.tar.gz --exclude=node_modules --exclude=.git app/ - 多个排除可重复写
--exclude=xxx,顺序无关 - 大量排除项建议写进文件,用
--exclude-from=exclude.list,每行一个路径模式
--exclude 匹配的是归档内的路径名,不是你执行命令时的当前路径。所以 --exclude=logs/*.log 有效,但 --exclude=/var/log/*.log 无效(因为归档里没有 /var/log 这种绝对路径)。
--exclude 写错或 -C 没用对,会导致压缩包内容缺失或冗余。动手前先用 tar -tzf xxx.tar.gz | head -20 看一眼内容是否符合预期。











