Linux: Archives and Compression
Data backup is the lifeline of operations. On Linux, tar + gzip is the most universal archiving solution, and rsync is the most powerful incremental sync tool.
📋 Prerequisites: You should already know
- Lesson 18: Package Management
1. What You'll Learn
- tar: create and extract archives
- gzip vs bzip2 vs xz compression algorithms
- zip: cross-platform compression
- rsync: incremental sync
- Automated backup strategies
2. A Story of "Forgetting the Exclude Parameter"
(1) The Pain Point: Packed Things That Shouldn't Be Packed
Xiaoming needed to send a project folder to a colleague — the team agreed not to transfer node_modules and .git directories because they're too large and unnecessary.
(2) One Command for a Perfect Archive
tar -czf project.tar.gz \
--exclude=node_modules \
--exclude=.git \
--exclude=__pycache__ \
project/
(3) The Benefit: A Clean Package
Xiaoming's compressed archive went from 500MB (with node_modules) down to 2MB. His colleague could use it right after extracting.
3. Knowledge Points
(1) tar — Archiving Tool
# Create tar archive
tar -cf archive.tar file1 file2 dir/ # Archive
tar -czf archive.tar.gz dir/ # Archive + gzip compression
> 💡 Tip: `tar -czf` option mnemonic — `c` (create), `z` (gzip compress), `f` (file, specify filename). This is the most common combination; the resulting `.tar.gz` file is the standard distribution format in the Linux world. To extract, just replace `c` with `x` (extract): `tar -xzf`.
tar -cjf archive.tar.bz2 dir/ # Archive + bzip2 compression
tar -cJf archive.tar.xz dir/ # Archive + xz compression
# Extract
tar -xf archive.tar # Extract (auto-detects format)
tar -xzf archive.tar.gz # Extract .tar.gz
tar -xf archive.tar -C /target/dir/ # Extract to specified directory
# View contents
tar -tf archive.tar.gz # Preview file list inside archive
> ⚠️ Warning: Before extracting a tar archive, use `tar -tf` to preview the file list — confirm there are no "bomb files" (e.g., files that extract to massive numbers of small files, or paths starting with `/` indicating absolute paths), to avoid overwriting system files or filling up disk space.
# Exclude
tar -czf backup.tar.gz --exclude="*.log" --exclude=node_modules dir/
| tar Option | Meaning |
|---|---|
-c |
Create archive |
-x |
Extract |
-t |
List contents |
-f |
Specify archive filename |
-z |
Filter through gzip |
-j |
Filter through bzip2 |
-J |
Filter through xz |
-v |
Show processed files |
-C |
Extract to specified directory |
--exclude |
Exclude files matching pattern |
(2) Compression Algorithm Comparison
| Algorithm | Extension | Option | Compression Ratio | Speed | Use Case |
|---|---|---|---|---|---|
| gzip | .gz |
-z |
Medium | Fast | Daily backup and distribution |
| bzip2 | .bz2 |
-j |
High | Slow | When higher compression is needed |
| xz | .xz |
-J |
Highest | Slowest | Long-term archiving, minimum size |
(3) zip/unzip — Cross-Platform Compression
# Compress
zip -r project.zip project/ # Recursively compress directory
zip -r project.zip project/ -x "*.git*" # Exclude .git
zip -r project.zip project/ -P password # Encrypt
# Extract
unzip project.zip # Extract to current directory
unzip project.zip -d /target/dir/ # Extract to specified directory
unzip -l project.zip # View contents without extracting
# zip advantage: natively supported on all operating systems
(4) rsync — Incremental Sync
# Basic usage
rsync -av source/ destination/ # Local sync (recursive + preserve attributes)
rsync -av --delete source/ dest/ # Sync and delete files in dest that aren't in source
> ℹ️ Note: `rsync --delete` makes the destination match the source exactly — files in the destination that don't exist in the source will be deleted. If you make a mistake (e.g., wrong source path), it could delete a large amount of destination data. Always add `--dry-run` first to preview operations before executing.
rsync -avz source/ user@host:/dest/ # Remote sync (compressed transfer)
rsync -avz -e "ssh -p 2222" source/ host:/dest/ # Specify SSH port
# Exclude
rsync -av --exclude="node_modules" --exclude=".git" src/ dst/
# Incremental backup (hard links)
rsync -av --link-dest=../backup-yesterday/ src/ backup-today/
rsync Advantages:
- Incremental transfer (only sends changed parts)
- Supports compressed transfer (
-z) - Resume interrupted transfers
- Secure transfer via SSH
(5) ▶ Example: tar Archive and Extract
# Archive the projects directory under home
tar -czf projects-backup.tar.gz ~/projects/
# View archive contents
tar -tf projects-backup.tar.gz | head -10
# Extract to /tmp
tar -xzf projects-backup.tar.gz -C /tmp/
# With verbose output
tar -czvf my-backup.tar.gz --exclude="*.log" /var/log/
(6) ▶ Example: Compression Algorithm Comparison
# Prepare test data
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
# Comparison results
# Typically: test.tar.gz is largest but fastest, test.tar.xz is smallest but slowest
Output:
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
(7) ▶ Example: zip Cross-Platform Distribution
# Archive a project (excluding unneeded directories)
cd ~/projects
zip -r myapp.zip myapp/ -x "myapp/node_modules/*" "myapp/.git/*" "myapp/__pycache__/*"
# View contents
unzip -l myapp.zip | head -20
# Encrypt archive
zip -r -e secret.zip confidential/ # Will prompt for password
(8) ▶ Example: rsync Backup
# Local backup
rsync -av --delete ~/projects/ /backup/projects/
# Remote backup to server
rsync -avz -e "ssh -i ~/.ssh/mykey" \
--exclude="node_modules" \
--progress \
~/projects/ user@backup-server:/backups/
# Incremental backup (using hard links)
# Day 1
rsync -av /data/ /backup/2026-07-07/
# Day 2 (only stores changes)
rsync -av --link-dest=/backup/2026-07-07/ /data/ /backup/2026-07-08/
Output:
TEXTsending 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
(9) ▶ Example: Automated Backup Script
#!/bin/bash
# auto-backup.sh - Automated backup of critical directories
BACKUP_ROOT="/backup"
DATE=$(date +%Y%m%d)
RETENTION_DAYS=30
# Directories to back up
declare -A DIRS
DIRS["projects"]="$HOME/projects"
DIRS["configs"]="/etc"
DIRS["notes"]="$HOME/notes"
echo "=== Starting backup: $DATE ==="
# Create backup directory
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 "Backing up $src → $dest"
tar -czf "$dest" \
--exclude="node_modules" \
--exclude=".git" \
--exclude="*.log" \
"$src" 2>/dev/null
echo " ✅ $(du -h "$dest" | cut -f1)"
else
echo " ⚠️ Directory does not exist: $src"
fi
done
# Delete expired backups
echo ""
echo "Cleaning backups older than $RETENTION_DAYS days..."
find "$BACKUP_ROOT" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
echo "=== Backup complete ==="
Output:
TEXT=== Starting backup: 20260707 === Backing up /home/alice/projects → /backup/20260707/projects.tar.gz ✅ 12M Backing up /etc → /backup/20260707/configs.tar.gz ✅ 4.5M Backing up /home/alice/notes → /backup/20260707/notes.tar.gz ✅ 256K Cleaning backups older than 30 days... === Backup complete ===
(10) ▶ Comprehensive Example: Complete rsync Backup Solution
#!/bin/bash
# rsync-backup.sh - Incremental backup using 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 "Starting backup of $SOURCE..."
# Perform remote incremental backup using 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 "✅ Backup succeeded"
# Create timestamped snapshot
ssh -i ~/.ssh/backup_key "${DEST_USER}@${DEST_HOST}" \
"cp -al ${DEST_PATH}/current ${DEST_PATH}/${TIMESTAMP}"
log "✅ Snapshot created: $TIMESTAMP"
else
log "❌ Backup failed (exit code: $?)"
exit 1
fi
❓ FAQ
Q: What's the relationship between tar and gzip? A: tar only handles archiving (combining multiple files into one), not compression. gzip handles compression. The common combination
tar -czfis equivalent to tar archive → gzip compress. File extensions:.tar.gzor.tgz.
Q: What do
-c,-z,-fmean intar -czf? A:-c(create) creates the archive,-z(gzip) compresses with gzip,-f(file) specifies the archive filename. The shorthandtar -czfcan also be written astar -c -z -f.
Q: Which is better for cross-platform use, zip or tar.gz? A: zip has better cross-platform compatibility — Windows/macOS/Linux all natively support it. tar.gz is the standard in the Linux/Unix world; Windows needs third-party tools like 7-Zip.
Q: What makes rsync faster than scp? A: rsync uses an incremental transfer algorithm — it only sends the changed parts of files. scp always copies entire files. For repeated transfers of the same files with small changes, rsync is much faster.
Q: How to do incremental instead of full backups? A: rsync inherently only transfers increments (changed parts). Combined with
--link-destto create hard-link snapshots: the first run is full, then each day use--link-destreferencing the previous day's snapshot, storing only the changes.
📖 Summary
tar -czfarchive and compress,tar -xfextract,tar -tfview contents--excludeexcludes unneeded files- gzip is fastest, xz has the best compression ratio, zip is most cross-platform
rsync -avzincremental sync,--deleteremoves extra files on destination--link-destcreates hard-link-based incremental snapshots
📝 Exercises
- Basic (⭐): Archive
~/projectsor a test directory asbackup.tar.gz, use-vto observe the process, then usetar -tfto view the file list inside - Intermediate (⭐⭐): Extract to
/tmp/testand verify file integrity, then create a test directory, zip it (excluding a subdirectory), and unzip to another location - Challenge (⭐⭐⭐): Use rsync to sync a local directory to
/tmp/backup/, verify incremental transfer (modify a file and sync again, observing only the change was transferred), then write a backup script supporting both tar.gz full backup and rsync incremental backup modes