Signal9Signal9 — home
online
all lessons

Archiving & Compression: tar, gzip & the .tar.gz Workflow

Beginner25 min5 steps
What you'll learn
  • 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
  1. 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, or xz.

    These are independent. tar by itself bundles but does not shrink — a plain .tar is 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 gzip alone on Linux the way you might on other systems — gzip compresses one file at a time. You bundle first with tar, then compress. tar knows 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?

  2. tar's three modes: create, list, extract

    Learn the three things tar does and the flags that select them — always with -f.

    tar has 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. -f is 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 and tar -xzf name.tar.gz to unpack one. Read -czf as "create, gzip, into this file", and -xzf as "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.tar
    project/
    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.
  3. 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.xz often 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?

  4. 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 -x writes 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 cd into 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 unpack
    project
    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.
  5. 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.gz
    demo/
    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 f
    restore/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 done
    identical
    --- 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.
Recap
  • 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.
tar & compression at a glance
You writeEffect
tar -czf out.tar.gz dir/create a gzip-compressed archive of dir/
tar -tzf out.tar.gzlist the contents (look before you extract)
tar -xzf out.tar.gzextract into the current directory
tar -xzf out.tar.gz -C /pathextract into /path instead
tar -cJf out.tar.xz dir/create an xz archive (smallest)
gzip file / gunzip file.gzcompress / decompress a single file