Sign in
← Linux: tools
10 min · easy · Lesson 4 of 4

Archives: tar, gzip, compression

How to pack and unpack tar archives, how archiving differs from compression, and which formats you'll run into at work.

A site backup, a release from CI, old logs after rotation all come to you as an archive. You need to be able to build one so it can later be extracted anywhere, and extract someone else's without dumping files all over your current directory. tar and a couple of compressors are all you need for that.

Where to practice

The examples below are meant for an ubuntu:24.04 container. Start the same one:

docker run --rm -it ubuntu:24.04 bash

Inside, you're root. After exit the container is removed along with all its files.

This image only has gzip. For xz, zstd and bzip2 you need the xz-utils, zstd and bzip2 packages, without them tar fails:

tar cJf apt.tar.xz -C /etc apt
/bin/sh: 1: xz: not found
tar: apt.tar.xz: Cannot write: Broken pipe
tar: Child returned status 127
tar: Error is not recoverable: exiting now

In labs 2 and 3 the image already has the packages you need.

On macOS the tar command is bsdtar (libarchive). The flags from this lesson, c, x, t, f, z and -C, work the same way there.

Archiving and compression: two different operations

The two operations usually go together, but they do different things:

On Linux, the two are combined: tar collects a tree of files into one stream, and a compressor shrinks it. That's where extensions like .tar.gz come from: tar first, then gzip. The short form of the same thing is .tgz.

tar: pack, list, extract

The tar flags are easier to remember by what they stand for: c create, x extract, t list, f file (the archive's name), v verbose, z through gzip.

tar czf backup.tar.gz /var/www          # create a compressed archive of a directory
tar tzf backup.tar.gz                   # list what's inside without extracting
tar xzf backup.tar.gz                   # extract into the current directory
tar xzf backup.tar.gz -C /restore       # extract into /restore

czf means "create, compress with gzip, into a file", xzf means "extract, gzip, from a file". The -C flag sets where to extract. The directory has to already exist, tar won't create it for you:

tar: /restore: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

So before extracting into a new place, you need mkdir -p /restore.

With v, tar prints every file. Combined with t that's a detailed listing: permissions, owner, size, date.

tar tvzf backup.tar.gz
drwxr-xr-x root/root         0 2026-10-09 08:26 var/www/
drwxr-xr-x root/root         0 2026-10-09 08:26 var/www/site/
-rw-r--r-- root/root         3 2026-10-09 08:26 var/www/site/index.html

You pull a single file out of an archive by naming its path exactly as it's recorded in the archive: tar xzf backup.tar.gz var/www/site/index.html. If that path doesn't exist, tar prints Not found in archive.

Paths inside the archive

tar records paths exactly as you pass them. It strips a leading / and warns about it:

tar czf backup.tar.gz /var/www
tar: Removing leading `/' from member names

Inside, you'll end up with var/www/site/index.html. Extract an archive like that into /restore, and you get /restore/var/www/site/..., with extra levels of directories.

To make paths start from the directory you want, move into its parent with the -C flag before the name. The flag applies to everything that comes after it:

tar czf site.tar.gz -C /var/www site
tar tzf site.tar.gz
site/
site/index.html
site/css/
site/css/a.css

An archive like that extracts into any directory as a single site/ folder.

You exclude what you don't need with the --exclude flag. The pattern is compared against the path in the archive, so for -C /var/www site you'd write --exclude=site/css. The shorter --exclude=css also works, but it throws out every file and directory named css at any depth.

Owners and permissions on extraction

tar preserves each file's owner and permissions. What you get back on extraction depends on who's extracting:

This matters when restoring a backup: a site extracted by a regular user will belong to that user, not to www-data.

Compression formats

Compressors differ in speed and compression ratio:

tar invokes them through flags: z is gzip, j is bzip2, J is xz, --zstd is zstd. The a flag (--auto-compress) picks the compressor by extension when creating an archive: tar caf logs.tar.zst logs/ compresses with zstd.

For single files, old logs for example, you don't need tar at all:

gzip -k app.log          # app.log.gz appears alongside it, the original stays (without -k it's removed)
gunzip app.log.gz        # back
zcat app.log.gz | tail   # read it without extracting to disk
zgrep ERROR app.log.gz   # search inside the compressed file

How tar detects the format on extraction

When extracting a file, GNU tar looks at the archive's first bytes (the signature), not at the extension. That's why tar xf with no z, J or --zstd will extract .tar.gz, .tar.xz and .tar.zst alike, as long as the right compressor is installed.

A format flag, on the other hand, can get in the way. If a file is named .tar.gz but holds a different format inside, tar xzf dutifully runs gzip, and gzip fails:

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

You can check the signature yourself: od -An -tx1 -N4 <file>. gzip starts with 1f 8b, xz with fd 37 7a 58, zstd with 28 b5 2f fd.

Auto-detection only works with a file. If an archive arrives through a pipe (curl ... | tar x), tar prints Archive is compressed. Use -z option, and you need the format flag.

Where this shows up at work

CI passes build artifacts around as .tar.gz, logs get rotated into compressed files, backups get packed into compressed archives. Even if you never build an archive yourself, you'll have to look inside and extract someone else's release or backup at some point.

Common mistakes

What to remember

Archiving (tar) glues files into one, keeping structure, permissions and owners. Compression (gzip, zstd, xz) shrinks the size. The two get combined, hence .tar.gz.

tar flags: c create, x extract, t list, f file, z gzip, -C change directory. Before extracting someone else's archive, look at its contents with tar tzf.

gzip is everywhere, zstd is faster at the same compression, xz compresses harder but slower. On extraction, tar figures out the format itself from the first bytes of the file.

This closes out the linux-tools track: users, host networking, regexes and archives. The mini-project in lab 3 brings them all together.

What you'll need for the tasks

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 3 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson linux-tools-04-archives