Archiving & Compression: tar, gzip & the .tar.gz Workflow
- Explain that bundling (tar) and compressing (gzip/xz) are two separate jobs, and that .tar.gz does both in order
- Run tar's three modes — create (-c), list (-t), extract (-x) — always with -f, and read what the letters mean
- Add compression with -z (gzip), -j (bzip2), or -J (xz), and pick one by the speed-vs-size tradeoff
- Extract safely: list an archive before unpacking it, extract into a clean directory with -C, and watch for tarbombs
Two jobs: bundling and compressing
Separate the two ideas that .tar.gz combines — packing many files into one, and shrinking bytes.
Whenever you download source code, move a project between machines, or make a backup, you meet a file like
project.tar.gz. Understanding it comes down to seeing that two separate jobs are happening:- Bundling — packing a whole directory tree (many files and folders) into a single file called an archive. On Unix this is `tar`'s job. Historically the name means tape archive, but today it's how you turn a folder into one movable file.
- Compressing — making that file smaller by squeezing out redundancy. That's a compressor like `gzip`,
bzip2, orxz.
These are independent.
tarby itself bundles but does not shrink — a plain.taris often about the same size as the files inside. A compressor by itself shrinks a single file but can't bundle a directory. The everyday.tar.gz(also written.tgz) is simply both, in order: tar bundles the tree into one.tar, then gzip compresses that into.tar.gz. The double extension literally tells you the two steps.This is why you can't just "zip a folder" with
gzipalone on Linux the way you might on other systems —gzipcompresses one file at a time. You bundle first withtar, then compress.tarknows how to do both in a single command, which is what makes it the tool everyone reaches for.Check yourself
In a file named backup.tar.gz, which part did tar do and which part did gzip do?
tar's three modes: create, list, extract
Learn the three things tar does and the flags that select them — always with -f.
tarhas three main modes, and you pick exactly one each time:- `-c` — create a new archive from files.
- `-t` — list (the table of contents) — show what's inside without unpacking.
- `-x` — extract — unpack the contents back out.
Every one of these is paired with `-f FILE`, which names the archive file to read or write.
-fis not optional in practice — it tells tar the archive is a file (not a tape). A useful memory aid: `-f` comes last among the clustered letters because the filename follows it.Two more letters you'll add constantly:
- `-v` — verbose: print each file as it's processed, so you can see what happened.
- `-z` — run the archive through gzip (covered next).
So the two commands you'll type most are
tar -czf name.tar.gz dir/to make an archive andtar -xzf name.tar.gzto unpack one. Read-czfas "create, gzip, into this file", and-xzfas "extract, un-gzip, from this file".Example — not runnable on your lab box
tar -cvf project.tar project/project/ project/main.c project/README.md
Create (-c) a plain (uncompressed) archive into the file (-f) project.tar from the project/ directory, verbosely (-v) so tar lists each entry as it packs it. The result is one file containing the whole tree — bundled, but not yet compressed. Example — not runnable on your lab box
tar -tf project.tarproject/ project/main.c project/README.md
List (-t) the table of contents of the archive without extracting anything. This is how you inspect an archive before trusting it — you see exactly what would be unpacked and where. Adding compression: -z, -j, -J
Choose a compressor by the speed-versus-size tradeoff.
To compress while archiving, add one compressor letter. tar runs the archive through that compressor on the way out (and reverses it on the way in):
- `-z` → gzip →
.tar.gz/.tgz. Fast, everywhere, moderate compression. The safe default. - `-j` → bzip2 →
.tar.bz2. Slower, smaller than gzip. - `-J` (capital) → xz →
.tar.xz. Slowest, usually the smallest. Common for source releases and kernels.
The tradeoff is speed versus size: gzip is quick and good enough for most day-to-day use; xz squeezes hardest but takes longer and more memory. Match the tool to the goal — gzip for a quick transfer, xz when the download size really matters. (Newer systems also have zstd via
--zstd/.tar.zst, which gets near-xz ratios at gzip-like speed.)The golden rule: extract with the same letter you created with, or just let tar autodetect. Modern GNU tar can usually figure out the compressor from the file on extract, so
tar -xf archive.tar.xzoften works without-J— but being explicit never hurts.Standalone, `gzip file` compresses a single file to
file.gz(replacing the original), and `gunzip file.gz` reverses it. That's for one file; for a directory you still bundle with tar first.Example — not runnable on your lab box
tar -czf project.tar.gz project/ && ls -l project.tar project.tar.gz | awk '{print $5, $9}'10240 project.tar 312 project.tar.gz
Create a gzip-compressed archive (-z) and compare sizes. The compressed .tar.gz is a fraction of the plain .tar — same contents, fewer bytes. That size drop is exactly what the -z (gzip) step bought you. Check yourself
You want the smallest possible archive for a source release and don't mind it taking longer to compress. Which tar compressor letter fits best?
- `-z` → gzip →
Extracting safely: look before you unpack
Unpack archives without scattering files or falling for a tarbomb.
Extraction unpacks files into your current directory — which is where two classic surprises come from:
- A tarbomb: an archive whose files are not inside a single top folder, so extracting it dumps dozens of loose files right into your current directory, mixed in with everything else.
- Where things land:
tar -xwrites relative to where you're standing, so running it in your home directory scatters the contents there.
Two habits prevent both:
1. List before you extract —
tar -tf archive.tar.gz. If everything is under one top-level directory (e.g.project/…), it's tidy. If you see loose files at the top, it's a tarbomb — make a directory to catch them.2. Extract into a directory you control — either
cdinto a fresh empty directory first, or use `-C DIR` to tell tar where to unpack:tar -xzf archive.tar.gz -C /tmp/unpack. The directory must already exist.One more caution: only extract archives you trust. A malicious archive can contain absolute paths or
..entries that try to write outside the target. GNU tar strips a leading/by default, but the safe move with anything unfamiliar is to list it first and unpack into a throwaway directory.Example — not runnable on your lab box
mkdir -p unpack && tar -xzf project.tar.gz -C unpack && ls unpackproject
Make a clean directory, then extract (-x) the gzip archive (-z) from the file (-f) INTO unpack (-C unpack). Everything lands under unpack/ instead of scattering into the current directory — the safe way to open an archive you didn't make. Now do it — round-trip a directory
Create, inspect, and unpack an archive end to end.
One continuous experiment: build a small tree, bundle-and-compress it, peek inside without unpacking, then extract it into a clean directory and confirm it round-tripped.
mkdir -p demo/src && printf 'int main(){}\n' > demo/src/main.c && printf 'hello\n' > demo/README && tar -czf demo.tar.gz demo/ && ls -l demo.tar.gz | awk '{print $5, $9}'234 demo.tar.gz
Build a demo/ tree with two files, then create a gzip-compressed archive of the whole directory in one command (-czf). You now have a single small file holding the entire tree — ready to move or store. tar -tzf demo.tar.gzdemo/ demo/src/ demo/src/main.c demo/README
List (-t) the gzip archive (-z) from the file (-f) to see its contents without extracting. Everything is neatly under a single top directory 'demo/', so this is well-behaved — not a tarbomb. This peek is the habit to build before every extract. mkdir -p restore && tar -xzf demo.tar.gz -C restore && find restore -type frestore/demo/src/main.c restore/demo/README
Extract into a clean 'restore' directory with -C. The find confirms both files came back intact, nested exactly as they were packed. The directory round-tripped through the archive without loss — bundle, compress, move, decompress, unbundle. diff demo/src/main.c restore/demo/src/main.c && echo 'identical'; echo '--- cleaning up ---'; rm -r demo restore demo.tar.gz project project.tar project.tar.gz unpack 2>/dev/null; echo doneidentical --- cleaning up --- done
diff proves the extracted file is byte-for-byte the same as the original — compression is lossless, so what goes in comes back out exactly. Then we clean up the demo files. You've now created, compressed, inspected, and safely extracted an archive: the whole tar workflow.
- A .tar.gz is two jobs in order: tar BUNDLES a directory tree into one archive, then gzip COMPRESSES it. tar alone doesn't shrink; a compressor alone can't bundle a folder.
- tar picks one mode each time: -c create, -t list, -x extract — always paired with -f FILE (keep -f last in the cluster, archive name right after).
- Add a compressor letter: -z gzip (.tar.gz, fast default), -j bzip2 (.tar.bz2), -J xz (.tar.xz, smallest but slowest). Extract with the same letter, or let modern tar autodetect.
- Extract safely: tar -tf to list an archive before unpacking, then extract into a fresh empty directory (or use -C DIR) so a tarbomb can't scatter files into your current folder.
| You write | Effect |
|---|---|
| tar -czf out.tar.gz dir/ | create a gzip-compressed archive of dir/ |
| tar -tzf out.tar.gz | list the contents (look before you extract) |
| tar -xzf out.tar.gz | extract into the current directory |
| tar -xzf out.tar.gz -C /path | extract into /path instead |
| tar -cJf out.tar.xz dir/ | create an xz archive (smallest) |
| gzip file / gunzip file.gz | compress / decompress a single file |
