这个命令是干啥的
tar 最开始是 Tape Archive(磁带归档)的缩写,就是用来把一堆文件塞到一个磁带上的工具。现在虽然没人用磁带了,但 tar 依然是 Linux 上打包和压缩的标配。
它的核心能力很简单:把一堆文件和目录打包成一个文件,然后可以配合 gzip、bzip2、xz 等压缩工具把包压小。
我经常碰到有人搞不清 tar 的参数,每次都用 man 查半天。其实常用的就那几个组合,记住之后就再也不用查了。
我刚工作那会,第一次被要求传一个项目目录给客户,我直接 zip -r project.zip project/,结果同事说:"在 Linux 上大家都用 tar.gz,别用 zip。"我当时还挺不服的,后来发现 tar.gz 在保留权限、符号链接、硬链接方面确实比 zip 强多了。
基本用法(3分钟上手)
创建 tar.gz 压缩包
# 把 myproject 目录打包压缩成 myproject.tar.gz
tar -czf myproject.tar.gz myproject/
这就是最常见的用法,记住三个字母:
- ·
-c:create,创建打包文件 - ·
-z:gzip 压缩(得到 .tar.gz 或 .tgz) - ·
-f:指定打包输出的文件名
解压 tar.gz
# 解压 myproject.tar.gz
tar -xzf myproject.tar.gz
- ·
-x:extract,解压 - ·
-z:gzip(因为包是 gzip 压缩的) - ·
-f:指定包文件名
只看不解压
# 列出 tar.gz 包里的内容
tar -tzf myproject.tar.gz
这三个组合(-czf、-xzf、-tzf)覆盖了 90% 的使用场景,记住它们就够了。
进阶骚操作
-C:解压到指定目录
# 解压到 /tmp 目录下
tar -xzf myproject.tar.gz -C /tmp
这个参数特别重要。默认 tar 解压到当前目录,如果不指定的话,解出来的文件就会散在你当前目录下。
# 创建包时指定目录结构
tar -czf backup.tar.gz -C /var/log .
这条意思是先 cd /var/log,然后把当前目录下的所有文件打包。这样打出来的包里就不会包含 /var/log 这个路径前缀。
--exclude:排除不需要的文件
# 打包时排除.git目录和node_modules
tar -czf project.tar.gz --exclude=.git --exclude=node_modules myproject/
# 通配符排除
tar -czf source.tar.gz --exclude="*.log" --exclude="*.tmp" src/
-v 显示详细信息
# 显示打包或解压的每个文件
tar -czvf myproject.tar.gz myproject/
加上 -v 后,屏幕会一行行打印正在处理的文件名。我一般开始打包的时候不加 -v,但有时候想看下进度(尤其是大文件打包时),就会加。
--strip-components:去掉目录层级
# 假设包里有 project/src/index.js,解压时去掉第一级目录
tar -xzf project.tar.gz --strip-components=1
# 这样解出来是 src/index.js,而不是 project/src/index.js
这个在解压别人发的包时特别有用。有时候发来的包套了好几层目录,或者目录名不对,--strip-components 直接去掉不需要的层级。
不解包查看内容
# 查看包内文件列表
tar -tzf backup.tar.gz
# 查看但不解压,过滤特定文件
tar -tzf backup.tar.gz | grep ".conf"
# 从包内提取单个文件
tar -xzf backup.tar.gz etc/nginx/nginx.conf
不!需!要!解!压!整!个!包!
很多新手不知道这个,每次想找一个文件就要先解压整个包,等很久。直接用 -t 查看,然后用 tar -xzf package.tar.gz 路径/文件名 只解压那一个文件。
避坑指南
坑1:-f 必须在所有选项最后
# 正确的写法
tar -czf myfile.tar.gz mydir/
# 错误的写法(报错)
tar -cfz myfile.tar.gz mydir/
tar -fcz myfile.tar.gz mydir/
-f 后面紧跟着文件名,所以它必须是选项组的最后一个字母。
坑2:绝对路径打包的隐患
# 这样打包会包含绝对路径
tar -czf /tmp/backup.tar.gz /home/user/project
解压的时候会在当前目录下创建 /home/user/project 这个路径。更安全的是:
# 先用 -C 切到目标目录再打包
tar -czf /tmp/backup.tar.gz -C /home/user project
这样解压出来只有 project/ 这一层。
坑3:覆盖已有文件
# 解压时如果目标目录已存在同名文件,默认会覆盖
tar -xzf backup.tar.gz -C /target
如果想备份旧文件,或者确认不会误覆盖,先 -t 看看内容。
坑4:tar 本身不压缩
# 不加 z/j/J 的话,tar 只是单纯打包,不压缩
tar -cf big.tar bigdir/
-z 调用 gzip,-j 调用 bzip2,-J 调用 xz。gzip 压缩率一般但速度最快,xz 压缩率最高但最慢。
坑5:大文件打包失败
# 文件太大磁盘空间不足
tar -czf huge.tar.gz huge_dir/
# 可能报错:write error: No space left on device
打包前先 du -sh 看下目录大小,确认有足够的空间放打包后的文件。打包后文件一般比源文件小,但也要留够余量。
实战场景
场景1:大文件归档分卷
如果 tar.gz 文件太大(超过 4G),单文件不好传输,可以分卷打包。
# 每卷不超过 1GB
tar -czf - bigdir/ | split -b 1G - bigdir.tar.gz.part_
# 合并并解压
cat bigdir.tar.gz.part_* | tar -xzf -
这个技巧我是在备份数据库目录时学到的。生产环境上一个项目目录压缩后还有 15G,直接 FTP 传老是断,分卷成 1G 的小包就好传多了。
场景2:增量备份
tar 支持增量备份,只打包变化过的文件。
# 第一次全量备份
tar -czf full_backup.tar.gz -g snapshot.snar mydir/
# 第二次增量备份(只打包变化过的文件)
tar -czf inc_backup_1.tar.gz -g snapshot.snar mydir/
-g 参数指定一个快照文件,tar 会记录哪些文件已经打过包了,下次再跑就只打包新增或修改过的。
# 恢复增量备份
tar -xzf full_backup.tar.gz -C /restore
tar -xzf inc_backup_1.tar.gz -C /restore
场景3:打包排除日志和缓存
# 打包web项目,排除日志和缓存
tar -czf webapp.tar.gz \
--exclude="*.log" \
--exclude="cache/" \
--exclude="node_modules" \
--exclude=".git" \
/var/www/myapp
场景4:远程传输打包数据
# 打包后通过ssh直接传到远程服务器(不落地)
tar -czf - /data/project | ssh user@remote "cat > /backup/project.tar.gz"
# 更进一步的用法:远程解压过去
tar -czf - /data/project | ssh user@remote "tar -xzf - -C /dest"
这样本地不留包,直接通过网络传输。我经常用这个方式来迁移小项目。
场景5:打包备份脚本
#!/bin/bash
# 每天备份项目目录,保留最近7天的备份
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www/myapp"
DATE=$(date +%Y%m%d)
# 打包并保留最近7份
tar -czf "$BACKUP_DIR/myapp_$DATE.tar.gz" \
-C /var/www myapp \
--exclude="*.log" \
--exclude="cache"
# 删除7天前的备份
find "$BACKUP_DIR" -name "myapp_*.tar.gz" -mtime +7 -delete
echo "备份完成:myapp_$DATE.tar.gz"
tar 和其他压缩格式
# tar.bz2(压缩率更高,速度较慢)
tar -cjf archive.tar.bz2 mydir/
tar -xjf archive.tar.bz2
# tar.xz(压缩率最高,最慢)
tar -cJf archive.tar.xz mydir/
tar -xJf archive.tar.xz
# 如果你拿到的是 .tar 或 .tar.gz 等格式,统一用自动识别
# tar 会自动根据文件后缀选择解压方式
tar -xf archive.tar.gz
tar -xf archive.tar.bz2
tar -xf archive.tar.xz
tar -xf archive.tar
这个 -a(auto-compress)选项从 tar 1.20 开始支持,会根据后缀判断压缩格式。不过我习惯了手动指定,因为心里更有底。
今日作业
你有 /data/project 目录(大约 500MB),请完成以下操作:
1. 打包压缩为 project_backup.tar.gz,排除 .git 目录和 *.log 文件
2. 查看包内文件列表,确认排除生效
3. 解压到 /tmp/restore 目录下(要求去掉第一级目录名)
写出这三条命令。