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:
- Archiving glues many files and directories into one file, keeping
structure, permissions and owners.
tardoes this. By itself, tar doesn't shrink anything. - Compression shrinks the data.
gzip,bzip2,zstdandxzdo this. They compress a single stream or file and know nothing about directories.
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:
- root gets files with the owners recorded in the archive (for example,
www-data); - a regular user gets files owned by themselves, while the permissions
(
rw-------and so on) are preserved.
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:
- gzip (
.gz): the default standard, fast, available everywhere, even in minimal images. - zstd (
.zst): modern, noticeably faster than gzip at comparable compression. It's increasingly the default choice. - xz (
.xz): compresses harder, but slower. Good for archives that sit around for a long time and are rarely extracted.
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
- Extracting without looking first. An archive with no common
directory (paths in the listing like
./README,./a/...) dumps its files straight into the current directory. Runtar tzffirst, then extract into a separate directory with-C. - The archive's name not right after
f. tar treats whatever word comes right afterfas the archive's name.tar czf -C /var/www sitecreates an archive named-Cand tries to pack/var/wwwandsite. Put flags like-Cafter the archive's name. - An absolute path when creating.
tar czf b.tar.gz /var/wwwgives youvar/www/...paths. You need-C /var/www <directory>. - No directory for
-C.Cannot open: No such file or directory, you needmkdir -p. - The format flag doesn't match the file.
not in gzip format: check the signature, or extract withtar xfand no flag. - The compressor isn't installed.
xz: not found,zstd: not found: install the package (xz-utils,zstd) or pick gzip. - The backup is visible to everyone. An archive is created with
permissions from umask, usually
644. If it holds logs or configs with passwords, lock it down:chmod 640and the right group.
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
- Enter a container with
docker exec -it <name> bashand exit withexit. - Create, list and extract an archive:
tar czf,tar tzf,tar xf,-C <directory>,--exclude,mkdir -p. - Compare two directories:
diff -r <directory1> <directory2>(empty output means "identical"). - Identify a format from its first bytes:
od -An -tx1 -N4 <file>. - For the mini-project, the module's other lessons too:
grep -E,zcat,sort | uniq -c(lesson 3),ss -ltnp(lesson 2),useradd,usermod -aG,su <name> -c,chown,chmod(lesson 1).
Done reading?
Mark the lesson as read to move your track progress forward.
Lesson marked as done.
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.
Tell the agent: use MCP izi, give me lesson linux-tools-04-archives
Progress saved in this browser
Clear your history or open this on your phone, and the marks will be gone. Leave your email and they'll move to your account. No password needed.
Done. moved to your account. You can see your progress on any device. My progress