tar and the archives you will be asked for
"Archive this directory and compress it" is a task you will be given, and the marks are in the details: which letter creates and which extracts, where the paths inside the archive come from, and whether the thing you extract lands where you meant. This guide also measures the four compressors on the same input rather than repeating the usual claims about them.
Essential Commands Guide 8 of 38 Intermediate
- PlatformsUbuntu 26.04 LTS + AlmaLinux 10.2
- LVM2.03.31 (Ubuntu) / 2.03.36 (AlmaLinux)
- nftables1.1.6 (Ubuntu) / 1.1.5 (AlmaLinux)
- TimeAbout 18 min
GNU tar. The compressor availability differs by distribution and is captured on both: Ubuntu 26.04 ships zstd and not bzip2, RHEL 10 the other way round.
- Firewallufw 0.36.2 enabled but reporting inactive / firewalld active
- Network confignetplan + systemd-networkd / NetworkManager 1.56.0
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| LFCS-A01 | 192.168.0.70 | Ubuntu 26.04 LTS | Primary host - most guides run only here | 2 Core | 4 GB | 50 GB |
| LFCS-C01 | 192.168.0.72 | AlmaLinux 10.2 | The other distribution - dnf, firewalld and NetworkManager | 2 Core | 4 GB | 50 GB |
This guide includes
Use this because "archive this directory and compress it" is a task you will be given. This matters because the paths stored inside decide what happens when somebody unpacks it - an absolute path makes it a different archive.
- creating, listing and extracting the same archive
- finding which compressors the machine actually has, and measuring all four
- seeing where the paths inside an archive come from
- dropping a leading directory with
--strip-components, and pulling one file out of many - checking what tar preserves, and the flag that changes it
Before you start
- guide 5 - the tree being archived.
-
Create, list, extract
The same archive, three operations.
bash Example session cd ~/ess/t && tar -cf site.tar site && ls -l site.tar | awk '{print $5, $9}'40960 site.tarcd ~/ess/t && tar -tf site.tar | head -5; echo "---"; tar -tf site.tar | wc -lsite/site/conf/site/conf/nginx.confsite/current.confsite/logs/---8cd ~/ess/t && tar -tvf site.tar | grep -E 'conf|current' | head -3drwxrwxr-x sysadmin/sysadmin 0 2026-08-29 09:44 site/conf/-rw-rw-r-- sysadmin/sysadmin 11 2026-08-29 09:44 site/conf/nginx.conflrwxrwxrwx sysadmin/sysadmin 0 2026-08-29 09:44 site/current.conf -> conf/nginx.confcd ~/ess/t && mkdir -p out && tar -xf site.tar -C out && find out | sort | head -6outout/siteout/site/confout/site/conf/nginx.confout/site/current.confout/site/logsExpected result40960 bytes, 8 entries, the symlink shown as
site/current.conf -> conf/nginx.conf, and the tree restored underout/.Success conditionYou can create, inspect and unpack an archive.
-
Which compressors the machine actually has
Six of them, looked for on both distributions.
bash Example session for z in gzip bzip2 xz zstd lz4 compress; do printf '%-9s %s\n' "$z" "$(command -v $z || echo 'NOT INSTALLED')"; donegzip /usr/bin/gzipbzip2 /usr/bin/bzip2xz /usr/bin/xzzstd /usr/bin/zstdlz4 NOT INSTALLEDcompress NOT INSTALLEDfor z in gzip bzip2 xz zstd lz4 compress; do printf '%-9s %s\n' "$z" "$(command -v $z || echo 'NOT INSTALLED')"; donegzip /usr/bin/gzipbzip2 /usr/bin/bzip2xz /usr/bin/xzzstd /usr/bin/zstdlz4 NOT INSTALLEDcompress NOT INSTALLEDsudo apt-get install -y -qq bzip2 2>&1 | tail -1; command -v bzip2 && bzip2 --version 2>&1 | head -1/usr/bin/bzip2bzip2, a block-sorting file compressor. Version 1.0.8, 13-Jul-2019.Expected resultUbuntu: gzip, xz, zstd - and bzip2 NOT INSTALLED. RHEL: gzip, bzip2, xz - and zstd NOT INSTALLED. Neither has lz4 or compress.
Success conditionYou know which flag will work before you type it.
-
The four compressors, measured
The same 5.16 MB of text, four times.
Read the caveat at the end - it matters.
bash Example session cd ~/ess/t && /usr/bin/time -f 'gzip %e s' tar -czf g.tar.gz sitegzip 0.09 scd ~/ess/t && /usr/bin/time -f 'bzip2 %e s' tar -cjf b.tar.bz2 sitebzip2 0.13 scd ~/ess/t && /usr/bin/time -f 'xz %e s' tar -cJf x.tar.xz sitexz 0.55 scd ~/ess/t && /usr/bin/time -f 'zstd %e s' tar --zstd -cf z.tar.zst sitezstd 0.00 scd ~/ess/t && b=$(stat -c %s plain.tar); for f in g.tar.gz b.tar.bz2 x.tar.xz z.tar.zst; do awk -v n="$f" -v s="$(stat -c %s $f)" -v b="$b" 'BEGIN{printf "%-12s %9d %5.2f%% of the plain tar\n", n, s, 100*s/b}'; doneg.tar.gz 1725266 33.43% of the plain tarb.tar.bz2 1060604 20.55% of the plain tarx.tar.xz 69444 1.35% of the plain tarz.tar.zst 82219 1.59% of the plain tarExpected resultgzip 0.10s / 33.43%, bzip2 0.13s / 20.57%, xz 0.57s / 1.26%, zstd 0.00s / 1.59%.
Success conditionYou can pick a compressor for a reason.
-
Where the paths inside come from
An absolute path, then the same directory archived with
-C.bash Example session cd ~/ess/t && tar -cf abs.tar /home/sysadmin/ess/t/site/conf 2>&1 | tail -2; tar -tf abs.tar | head -3tar: Removing leading `/' from member nameshome/sysadmin/ess/t/site/conf/home/sysadmin/ess/t/site/conf/nginx.confcd ~/ess/t && tar -cf rel.tar -C site conf && tar -tf rel.tar; echo "--- -C changes directory first, so the paths inside are relative"conf/conf/nginx.conf--- -C changes directory first, so the paths inside are relativeExpected result
tar: Removing leading '/' from member namesand entries ofhome/sysadmin/ess/t/site/conf/...; then-C site confgiving justconf/andconf/nginx.conf.Success conditionYou control what the paths inside look like.
-
--strip-components, and one file out of many
Dropping a leading directory on the way out, and extracting a single member.
bash Example session cd ~/ess/t && mkdir -p strip && tar -xf site.tar -C strip --strip-components=1 && find strip | sort | head -5; echo "--- --strip-components drops leading path elements"stripstrip/confstrip/conf/nginx.confstrip/current.confstrip/logs--- --strip-components drops leading path elementscd ~/ess/t && mkdir -p one && tar -xf site.tar -C one site/conf/nginx.conf && find one | sortoneone/siteone/site/confone/site/conf/nginx.confcd ~/ess/t && tar -tf site.tar --wildcards '*/conf/*' 2>/dev/null || tar -tf site.tar | grep confsite/conf/nginx.confExpected result
strip/conf,strip/logswith thesite/level gone; then onlyone/site/conf/nginx.confextracted.Success conditionYou can extract exactly what you need, where you need it.
-
What tar preserves, and the flag that changes it
Permissions through a round trip, and what
-hdoes to a symlink.bash Example session cd ~/ess/t && chmod 600 site/conf/nginx.conf && tar -cpf perms.tar site && rm -rf out2 && mkdir out2 && tar -xpf perms.tar -C out2 && stat -c '%A %n' site/conf/nginx.conf out2/site/conf/nginx.conf-rw------- site/conf/nginx.conf-rw------- out2/site/conf/nginx.confcd ~/ess/t && stat -c '%A %n' site/current.conf out2/site/current.conf; echo "--- the symlink came through as a symlink, not as a copy of the target"lrwxrwxrwx site/current.conflrwxrwxrwx out2/site/current.conf--- the symlink came through as a symlink, not as a copy of the targetcd ~/ess/t && tar -chf deref.tar site && mkdir -p out3 && tar -xf deref.tar -C out3 && stat -c '%A %s %n' out3/site/current.conf; echo "--- -h follows symlinks and archives the CONTENT instead"-rw------- 11 out3/site/current.conf--- -h follows symlinks and archives the CONTENT insteadExpected result
-rw-------on both the original and the extracted copy; the symlink still a symlink; and with-h,-rw------- 11- a regular file with the target's content.Success conditionYou know whether an extracted tree matches the original.
Troubleshooting
tar: Child returned status 127.Why: The compressor is not installed - bzip2 on Ubuntu, zstd on RHEL.
Fix:Read the line above it for the missing binary, and install it.
gzipalways works.Extracting sprayed files all over the current directory.
Why: The archive has no top-level directory - a tar bomb.
Fix:
tar -tffirst, always. Extract into an empty directory with-C.Extracted files landed under a deep path you did not want.
Why: The archive stored absolute or deep relative paths.
Fix:
--strip-components=N, or archive with-Cnext time.tar: Removing leading / from member names.Why: You archived an absolute path. It is a warning, not an error.
Fix:Use
-C /parent thingso the paths are relative to begin with.A restored tree has the wrong owners.
Why: It was extracted by a non-root user, so everything became theirs.
Fix:Extract as root with
--same-owner, which is the default for root.tar -cvfprinted the file list but created nothing useful.Why: The
-fargument was not the next word - the letter order matters.Fix:
-flast of the bundled flags, then the filename.