Linux: 压缩与归档——tar / gzip / zip 与数据备份
数据备份是运维的生命线。在 Linux 上,tar + gzip 是最通用的归档方案,rsync 是最强大的增量同步工具。
📋 前置知识:需要先掌握以下内容
- 第18课:包管理
1. 你将学到
- tar 打包和解包
- gzip vs bzip2 vs xz 压缩算法
- zip 跨平台压缩
- rsync 增量同步
- 自动备份策略
2. 一个 "忘加排除参数" 的故事
(1) 痛点:打包了不该打包的东西
小明需要把项目文件夹发给同事——团队约定不传输 node_modules 和 .git 目录,因为它们体积太大且不必要。
(2) 一条命令完美打包
BASH
tar -czf project.tar.gz \
--exclude=node_modules \
--exclude=.git \
--exclude=__pycache__ \
project/
(3) 收益:干净的包
小明的压缩包从 500MB(含 node_modules)降到了 2MB,同事解压后直接就能用。
3. 知识点讲解
(1) tar——打包工具
BASH
# 创建 tar 包
tar -cf archive.tar file1 file2 dir/ # 打包
tar -czf archive.tar.gz dir/ # 打包 + gzip 压缩
> 💡 **提示**:`tar -czf` 的选项助记——`c`(create 创建)、`z`(gzip 压缩)、`f`(file 指定文件名)。这是最常用的组合,生成的 `.tar.gz` 文件是 Linux 世界的标准分发格式。解压只需将 `c` 换成 `x`(extract):`tar -xzf`。
tar -cjf archive.tar.bz2 dir/ # 打包 + bzip2 压缩
tar -cJf archive.tar.xz dir/ # 打包 + xz 压缩
# 解包
tar -xf archive.tar # 解包(自动识别格式)
tar -xzf archive.tar.gz # 解压 .tar.gz
tar -xf archive.tar -C /target/dir/ # 解压到指定目录
# 查看内容
tar -tf archive.tar.gz # 预览包内文件列表
> ⚠️ **注意**:解压 tar 包前,先用 `tar -tf` 预览包内文件列表——确认没有"炸弹文件"(如解压出大量小文件或路径以 `/` 开头的绝对路径文件),避免覆盖系统文件或填满磁盘。
# 排除
tar -czf backup.tar.gz --exclude="*.log" --exclude=node_modules dir/
| tar 选项 | 含义 |
|---|---|
-c |
创建归档 |
-x |
解包 |
-t |
列出内容 |
-f |
指定归档文件名 |
-z |
通过 gzip 过滤 |
-j |
通过 bzip2 过滤 |
-J |
通过 xz 过滤 |
-v |
显示处理的文件 |
-C |
解压到指定目录 |
--exclude |
排除匹配模式的文件 |
(2) 压缩算法对比
| 算法 | 扩展名 | 选项 | 压缩比 | 速度 | 适用场景 |
|---|---|---|---|---|---|
| gzip | .gz |
-z |
中 | 快 | 日常备份和分发 |
| bzip2 | .bz2 |
-j |
高 | 慢 | 需要更高压缩比 |
| xz | .xz |
-J |
最高 | 最慢 | 长期归档,最小体积 |
(3) zip/unzip——跨平台压缩
TEXT
📖 仅展示
# 压缩
zip -r project.zip project/ # 递归压缩目录
zip -r project.zip project/ -x "*.git*" # 排除 .git
zip -r project.zip project/ -P password # 加密
# 解压
unzip project.zip # 解压到当前目录
unzip project.zip -d /target/dir/ # 解压到指定目录
unzip -l project.zip # 查看内容不解压
# zip 的优势:所有操作系统原生支持
(4) rsync——增量同步
BASH
# 基本用法
rsync -av source/ destination/ # 本地同步(递归 + 保留属性)
rsync -av --delete source/ dest/ # 同步并删除 dest 中源没有的文件
> ℹ️ **说明**:`rsync --delete` 会让目标端与源端完全一致——删除目标端有但源端没有的文件。如果误操作(如源路径写错),可能导致目标端数据大量丢失。建议先加 `--dry-run` 预览操作,确认无误后再实际执行。
rsync -avz source/ user@host:/dest/ # 远程同步(压缩传输)
rsync -avz -e "ssh -p 2222" source/ host:/dest/ # 指定 SSH 端口
# 排除
rsync -av --exclude="node_modules" --exclude=".git" src/ dst/
# 增量备份(硬链接)
rsync -av --link-dest=../backup-yesterday/ src/ backup-today/
rsync 的优势:
- 增量传输(只传变化的部分)
- 支持压缩传输(
-z) - 断点续传
- 通过 SSH 安全传输
▶ 示例:tar 打包和解包
TEXT
📖 仅展示
# 打包家目录下的 projects
tar -czf projects-backup.tar.gz ~/projects/
# 查看包内容
tar -tf projects-backup.tar.gz | head -10
# 解压到 /tmp
tar -xzf projects-backup.tar.gz -C /tmp/
# 带详细的输出
tar -czvf my-backup.tar.gz --exclude="*.log" /var/log/
▶ 示例:不同压缩算法对比
BASH
# 准备测试
mkdir -p /tmp/compress-test
cp -r /usr/share/doc/* /tmp/compress-test/ 2>/dev/null
# gzip
time tar -czf test.tar.gz -C /tmp compress-test
ls -lh test.tar.gz
# bzip2
time tar -cjf test.tar.bz2 -C /tmp compress-test
ls -lh test.tar.bz2
# xz
time tar -cJf test.tar.xz -C /tmp compress-test
ls -lh test.tar.xz
# 对比结果
# 通常:test.tar.gz 最大但最快,test.tar.xz 最小但最慢
输出:
TEXT 📖 仅展示-rw-r--r-- 1 alice alice 1.2M test.tar.gz real 0m0.234s user 0m0.198s sys 0m0.036s -rw-r--r-- 1 alice alice 856K test.tar.bz2 real 0m1.456s user 0m1.389s sys 0m0.067s -rw-r--r-- 1 alice alice 612K test.tar.xz real 0m5.123s user 0m4.987s sys 0m0.136s
▶ 示例:zip 跨平台分发
TEXT
📖 仅展示
# 打包项目(排除不需要的目录)
cd ~/projects
zip -r myapp.zip myapp/ -x "myapp/node_modules/*" "myapp/.git/*" "myapp/__pycache__/*"
# 查看内容
unzip -l myapp.zip | head -20
# 加密打包
zip -r -e secret.zip confidential/ # 会提示输入密码
▶ 示例:rsync 备份
BASH
# 本地备份
rsync -av --delete ~/projects/ /backup/projects/
# 远程备份到服务器
rsync -avz -e "ssh -i ~/.ssh/mykey" \
--exclude="node_modules" \
--progress \
~/projects/ user@backup-server:/backups/
# 增量备份(用硬链接)
# 第一天
rsync -av /data/ /backup/2026-07-07/
# 第二天(只存变化的部分)
rsync -av --link-dest=/backup/2026-07-07/ /data/ /backup/2026-07-08/
输出:
TEXT 📖 仅展示sending incremental file list sent 1,234 bytes received 512 bytes 2,492.00 bytes/sec total size is 5.6M speedup is 3,210.45 sending incremental file list app.js config.yaml sent 4,567 bytes received 128 bytes 9,390.00 bytes/sec total size is 5.6M speedup is 1,197.23
▶ 示例:自动备份脚本
BASH
#!/bin/bash
# auto-backup.sh - 自动备份关键目录
BACKUP_ROOT="/backup"
DATE=$(date +%Y%m%d)
RETENTION_DAYS=30
# 需要备份的目录
declare -A DIRS
DIRS["projects"]="$HOME/projects"
DIRS["configs"]="/etc"
DIRS["notes"]="$HOME/notes"
echo "=== 开始备份: $DATE ==="
# 创建备份目录
mkdir -p "$BACKUP_ROOT/$DATE"
for name in "${!DIRS[@]}"; do
src="${DIRS[$name]}"
dest="$BACKUP_ROOT/$DATE/$name.tar.gz"
if [ -d "$src" ]; then
echo "备份 $src → $dest"
tar -czf "$dest" \
--exclude="node_modules" \
--exclude=".git" \
--exclude="*.log" \
"$src" 2>/dev/null
echo " ✅ $(du -h "$dest" | cut -f1)"
else
echo " ⚠️ 目录不存在: $src"
fi
done
# 删除过期备份
echo ""
echo "清理 $RETENTION_DAYS 天前的备份..."
find "$BACKUP_ROOT" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
echo "=== 备份完成 ==="
输出:
TEXT 📖 仅展示=== 开始备份: 20260707 === 备份 /home/alice/projects → /backup/20260707/projects.tar.gz ✅ 12M 备份 /etc → /backup/20260707/configs.tar.gz ✅ 4.5M 备份 /home/alice/notes → /backup/20260707/notes.tar.gz ✅ 256K 清理 30 天前的备份... === 备份完成 ===
▶ 综合示例:完整的 rsync 备份方案
BASH
#!/bin/bash
# rsync-backup.sh - 使用 rsync 的增量备份
SOURCE="$HOME/projects/webapp"
DEST_USER="backup"
DEST_HOST="backup.example.com"
DEST_PATH="/backups/webapp"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOGFILE="/var/log/backup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOGFILE"
}
log "开始备份 $SOURCE..."
# 使用 rsync 进行远程增量备份
rsync -avz \
--delete \
--partial \
--progress \
--exclude="node_modules" \
--exclude=".git" \
--exclude=".env" \
--exclude="tmp/" \
-e "ssh -i ~/.ssh/backup_key -p 22" \
"$SOURCE/" \
"${DEST_USER}@${DEST_HOST}:${DEST_PATH}/current/" >> "$LOGFILE" 2>&1
if [ $? -eq 0 ]; then
log "✅ 备份成功"
# 创建带时间戳的快照
ssh -i ~/.ssh/backup_key "${DEST_USER}@${DEST_HOST}" \
"cp -al ${DEST_PATH}/current ${DEST_PATH}/${TIMESTAMP}"
log "✅ 快照创建: $TIMESTAMP"
else
log "❌ 备份失败 (exit code: $?)"
exit 1
fi
❓ 常见问题
Q: tar 和 gzip 是什么关系? A: tar 只负责打包(将多个文件合并成一个),不压缩。gzip 负责压缩。常用组合
tar -czf相当于 tar 打包 → gzip 压缩。扩展名.tar.gz或.tgz。
Q:
tar -czf中的-c、-z、-f分别代表什么? A:-c(create)创建归档,-z(gzip)通过 gzip 压缩,-f(file)指定归档文件名。简写tar -czf也可以写成tar -c -z -f。
Q: zip 和 tar.gz 哪个跨平台更好? A: zip 的跨平台兼容性更好——Windows/macOS/Linux 都原生支持。tar.gz 是 Linux/Unix 世界的标准,Windows 需要第三方工具(如 7-Zip)。
Q: rsync 比 scp 快在哪? A: \1
Q: 怎么增量备份而不是全量? A: rsync 本身只传增量(变化的部分)。结合
--link-dest创建硬链接快照:第一次全量,之后每天用--link-dest引用前一天的快照,只存储变化的部分。
📖 小节
tar -czf打包压缩、tar -xf解包、tar -tf查看--exclude排除不需要的文件- gzip 最快、xz 压缩比最高、zip 跨平台最好
rsync -avz增量同步,--delete删除目标端多余文件--link-dest创建基于硬链接的增量快照
📝 作业
- 基础题(难度⭐):将
~/projects或一个测试目录打包为backup.tar.gz,用-v观察过程,然后用tar -tf查看包内文件列表 - 进阶题(难度⭐⭐):解压到
/tmp/test目录并验证文件完整性,然后创建一个测试目录,用 zip 打包(排除某个子目录)并用 unzip 解压到另一处 - 挑战题(难度⭐⭐⭐):用 rsync 将本地一个目录同步到
/tmp/backup/,验证增量传输(修改一个文件后再同步,观察只传输了变化部分),然后写一个备份脚本支持 tar.gz 全量备份和 rsync 增量备份两种模式