tar —— 打包、压缩与备份
tar —— 打包、压缩与备份
分类:03 文件与传输 适用:全平台(GNU tar 1.3x / bsdtar) 一句话:Linux 备份与交付的通用容器,能保留权限、属主、软链接、SELinux 上下文。
1. 它解决什么问题
- 把目录打成单文件交付/备份。
- 保留权限、属主、时间戳、软链接(
cp容易丢)。 - 与压缩工具组合(gzip/zstd/xz),与 SSH 组合做流式传输。
- 增量备份(
--listed-incremental)。
2. 先记住三种操作
| 操作 | 参数 | 记忆 |
|---|---|---|
| 创建 | -c |
create |
| 解开 | -x |
extract |
| 列出 | -t |
list |
再加压缩:-z gzip、-j bzip2、-J xz、--zstd zstd、--lz4。
顺序很重要:
tar -czf中f必须紧跟归档文件名,写成tar -cfz会把z当文件名。
3. 基础用法
# 创建
tar -czf backup.tar.gz /data # gzip,最常用
tar -cjf backup.tar.bz2 /data # bzip2,压缩率高但慢
tar -cJf backup.tar.xz /data # xz,最高压缩比,最慢
tar --zstd -cf backup.tar.zst /data # zstd,速度与压缩比均衡(推荐)
tar -cf backup.tar /data # 不压缩
# 查看(不解压)
tar -tzf backup.tar.gz | head
tar -tzf backup.tar.gz | grep 'nginx.conf' # 找某个文件
# 解压
tar -xzf backup.tar.gz # 解到当前目录
tar -xzf backup.tar.gz -C /restore # 解到指定目录
tar -xzf backup.tar.gz path/to/file # 只解某个文件
tar -xzf backup.tar.gz --strip-components=1 # 去掉第一层目录
4. 关键参数
| 参数 | 作用 | 场景 |
|---|---|---|
-v |
显示处理文件 | 交互使用;脚本里会拖慢 |
-p |
保留权限 | 解压时以 root 运行默认保留 |
--numeric-owner |
按数字保留属主 | 跨系统恢复必用 |
-C <dir> |
切换目录 | 打包/解包指定位置 |
--exclude= |
排除 | 可多次 |
--exclude-from= |
从文件读排除 | |
-h / --dereference |
跟随软链接(存实体) | 默认存软链本身 |
-P / --absolute-names |
允许绝对路径 | 解压时危险,会覆盖原路径 |
--one-file-system |
不跨文件系统 | 备份 / 时必备 |
--warning=no-file-changed |
忽略"文件变化"警告 | 备份活动日志 |
--ignore-failed-read |
读失败继续 | 有坏文件时 |
-S |
处理稀疏文件 | 镜像/虚拟机磁盘 |
--totals |
输出总字节 | |
--checkpoint=.1000 |
每 1000 个文件打点 | 长任务看进度 |
-W / --verify |
写完校验 | 磁带/重要备份 |
--remove-files |
打包后删源 | 归档并清理 |
5. 流式与管道
# 打包直接传到远端(不落本地盘)
tar -czf - /data | ssh user@host 'tar -xzf - -C /backup'
# 边打包边算校验
tar -czf - /data | tee >(sha256sum > /tmp/sum.txt) | ssh host 'cat > /data.tar.gz'
# 从 stdin 解压
curl -sL https://example.com/pkg.tar.gz | tar -xzf - -C /opt
# 大目录跨机迁移加 pv 看进度
tar -cf - /data | pv | ssh host 'tar -xf - -C /backup'
# 拆包(超大文件分卷)
tar -czf - /data | split -b 2G - /backup/data.tar.gz.part_
cat /backup/data.tar.gz.part_* | tar -xzf - -C /restore
流式传输的好处是不占本地临时空间,坏处是中断要重来(用 rsync 更适合大体量)。
6. 排除规则
tar -czf backup.tar.gz \
--exclude='*.log' \
--exclude='./data/cache' \
--exclude='./data/tmp' \
-C / data
# 从文件读
cat > /tmp/exclude.txt <<'EOF'
data/cache
data/tmp
*.pid
EOF
tar -czf backup.tar.gz --exclude-from=/tmp/exclude.txt -C / data
要点:
- 相对路径基于
-C指定的目录。 *.log会匹配任意层级的 log 文件。- 排除目录要写对名字,末尾不要加
/(GNU tar 对目录匹配较宽松,但保持一致更稳)。
7. 实战场景
7.1 备份前先排除伪文件系统
tar -czf /backup/root-$(date +%F).tar.gz \
--one-file-system \
--exclude=/proc --exclude=/sys --exclude=/dev --exclude=/run \
--exclude=/tmp --exclude=/var/cache --exclude=/backup \
--warning=no-file-changed \
/ 2>/dev/null
--one-file-system 已经能挡住大部分挂载点,但显式排除更保险。
7.2 保留 SELinux 上下文
GNU tar 1.28+ 默认会保存 security.selinux xattr。老版本用:
tar --selinux -czf backup.tar.gz /var/www
# 恢复后
restorecon -Rv /var/www
7.3 增量备份
# 第一次:全量,生成快照文件
tar -czf /backup/full-$(date +%F).tar.gz --listed-incremental=/backup/snap.file /data
# 之后:增量
tar -czf /backup/inc-$(date +%F).tar.gz --listed-incremental=/backup/snap.file /data
# 恢复必须按顺序:full → inc1 → inc2 ...
tar 增量基于 mtime,改名/权限变化不一定被捕获;要求严格就用
rsync --link-dest或restic。
7.4 只解压部分文件
tar -tzf app.tar.gz | grep 'conf/'
tar -xzf app.tar.gz -C /tmp app/config/app.yml
7.5 恢复时去掉多余前缀
# 包里是 package-1.2.3/ 结构,想直接解到当前目录
tar -xzf pkg.tar.gz --strip-components=1 -C /opt/app
8. 常见坑
-f位置:tar -czf file.tar.gz dir正确;tar -cz file.tar.gz dir会当成无f报错或行为异常。- 打包时路径带
/开头:解压会覆盖原路径,务必用-C /+ 相对路径,或--absolute-names明确知道在干什么。 - 通配符被 shell 展开:
tar -czf a.tar.gz *.log在文件过多时会报Argument list too long,用--files-from或find -print0。 - 不保留属主:普通用户解压别人的包,属主变成自己;需要
--numeric-owner+ root。 - 软链接被展开:默认存链接本身,若想存实体用
-h(可能造成循环)。 - 打包正在写的文件:得到不一致内容,加
--warning=no-file-changed只是静音,不是解决。 - 解压覆盖无提示:GNU tar 默认直接覆盖,恢复前先
-t看清楚。 - Alpine 用 bsdtar:
--listed-incremental、--selinux等 GNU 专有参数不支持,装tar包或改用busybox tar的有限功能。 - 压缩级别:
gzip -1到-9差别有限;大数据量优先zstd -3,速度是 gzip 的数倍。 -z与--zstd不要同时用,会嵌套压缩。- 解压到只读文件系统/空间不足:先
df -h确认空间是包大小的 1.5~2 倍。
9. 压缩工具怎么选
| 工具 | 命令后缀 | 速度 | 压缩比 | 适用 |
|---|---|---|---|---|
| gzip | .tar.gz |
中 | 中 | 通用兼容 |
| bzip2 | .tar.bz2 |
慢 | 较高 | 已过时,少用 |
| xz | .tar.xz |
很慢 | 最高 | 长期归档、发行包 |
| zstd | .tar.zst |
快 | 高 | 推荐,可调级别 |
| lz4 | .tar.lz4 |
极快 | 低 | 临时传输 |
tar -I 'zstd -T0 -3' -cf backup.tar.zst /data # 多线程 zstd
zstd -d backup.tar.zst -o backup.tar
10. 速查表
tar -czf a.tar.gz dir/ # 打包 gzip
tar -cJf a.tar.xz dir/ # 打包 xz
tar --zstd -cf a.tar.zst dir/ # 打包 zstd
tar -tzf a.tar.gz # 列出
tar -xzf a.tar.gz -C /dest # 解压到目录
tar -xzf a.tar.gz --strip-components=1
tar -xzf a.tar.gz path/in/archive # 解单个文件
tar -czf a.tar.gz --exclude='*.log' dir/
tar -czf - dir/ | ssh host 'tar -xzf - -C /dest'
tar -czf a.tar.gz --one-file-system --exclude=/proc /
tar -czf b.tar.gz --listed-incremental=snap /data
tar -czf a.tar.gz --numeric-owner -C / data