Package Managers Deep Dive

Why This Matters

It is 2 AM and your monitoring system fires an alert: a critical security vulnerability has been disclosed in OpenSSL. Every server you manage needs to be patched before business hours. Without a package manager, you would need to manually download source code on each server, compile it, figure out which files to replace, and hope you do not break anything. With a package manager, the fix is one command per server -- or one Ansible playbook for all of them.

Package managers are the backbone of software management on Linux. They handle downloading software, resolving dependencies, tracking installed files, applying updates, and cleanly removing programs. Every Linux administrator uses a package manager dozens of times a day. Understanding how they work -- not just the basic commands, but the underlying architecture -- separates administrators who react to problems from those who prevent them.

This chapter takes you deep into the three major package management ecosystems: APT (Debian/Ubuntu), DNF/YUM (Fedora/RHEL), and Pacman (Arch Linux). By the end, you will be able to install, query, pin, clean, and troubleshoot packages on any major distribution.


Try This Right Now

Check which package manager your system uses and how many packages are currently installed:

# Debian/Ubuntu
$ dpkg --list | wc -l

# Fedora/RHEL
$ rpm -qa | wc -l

# Arch Linux
$ pacman -Q | wc -l

You will likely see hundreds or even thousands of packages. Every one of those was installed, tracked, and has its dependencies satisfied by your package manager.


What Package Managers Actually Do

A package manager is not just an installer. It is a database administrator, a dependency solver, a file tracker, and a download manager rolled into one.

┌──────────────────────────────────────────────────────────┐
│                  PACKAGE MANAGER                          │
│                                                           │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────┐  │
│  │  Repository  │  │  Dependency  │  │   Local         │  │
│  │  Metadata    │  │  Resolver    │  │   Database      │  │
│  │  (what's     │  │  (what else  │  │   (what's       │  │
│  │  available)  │  │  is needed)  │  │   installed)    │  │
│  └──────┬──────┘  └──────┬───────┘  └────────┬────────┘  │
│         │                │                    │           │
│         v                v                    v           │
│  ┌─────────────────────────────────────────────────────┐  │
│  │             Package Operations                      │  │
│  │  Install  |  Update  |  Remove  |  Query  | Verify  │  │
│  └─────────────────────────────────────────────────────┘  │
│                          │                                │
│                          v                                │
│  ┌─────────────────────────────────────────────────────┐  │
│  │               File System                           │  │
│  │   /usr/bin  /usr/lib  /etc  /usr/share  ...         │  │
│  └─────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────┘

The Core Functions

  1. Installation: Download a package and all its dependencies, verify integrity, extract files to the correct locations
  2. Dependency resolution: If package A needs libraries from packages B and C, install B and C first
  3. Tracking: Record every file installed by every package so nothing gets lost
  4. Updates: Compare installed versions against repository versions, upgrade what is outdated
  5. Removal: Remove a package and optionally its no-longer-needed dependencies
  6. Querying: Search for packages, list files owned by a package, find which package provides a file

Package Formats

The two dominant binary package formats on Linux are:

FormatExtensionUsed ByTool
Debian.debDebian, Ubuntu, Mint, Pop!_OSdpkg
RPM.rpmFedora, RHEL, CentOS, openSUSErpm

Arch Linux uses its own compressed tar archive format (.pkg.tar.zst).

Think About It: Why do Linux distributions use binary packages at all? Why not just distribute source code and compile everything on the user's machine? (Hint: think about time, resources, and reproducibility.)


The APT Ecosystem (Debian/Ubuntu)

APT is a layered system. Understanding the layers prevents confusion about which tool to use when.

┌───────────────────────────────────────────┐
│  apt (high-level, user-friendly CLI)      │  <-- Use this
├───────────────────────────────────────────┤
│  apt-get / apt-cache (classic CLI tools)  │  <-- Use in scripts
├───────────────────────────────────────────┤
│  libapt (APT library, C++)               │
├───────────────────────────────────────────┤
│  dpkg (low-level package installer)       │  <-- Installs .deb files
└───────────────────────────────────────────┘
  • dpkg: Installs, removes, and queries individual .deb files. Does not resolve dependencies or download packages.
  • apt-get / apt-cache: The classic high-level tools. They handle repositories, downloads, and dependency resolution. Stable interface, preferred in scripts.
  • apt: The modern unified command. Combines the most common functions of apt-get and apt-cache with a nicer interface (progress bars, color). Preferred for interactive use.

sources.list: Where Packages Come From

APT fetches packages from repositories defined in /etc/apt/sources.list and files under /etc/apt/sources.list.d/.

$ cat /etc/apt/sources.list

A typical entry looks like:

deb http://deb.debian.org/debian bookworm main contrib non-free-firmware
deb-src http://deb.debian.org/debian bookworm main contrib non-free-firmware
deb http://security.debian.org/debian-security bookworm-security main contrib non-free-firmware

Breaking down a line:

deb       http://deb.debian.org/debian   bookworm   main contrib non-free-firmware
^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^     ^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
type      repository URL                 release    components
(binary
or source)
  • deb: Binary packages. deb-src: Source packages.
  • URL: The mirror hosting the packages.
  • Release: The codename (bookworm, jammy) or class (stable, testing).
  • Components: Sections within the repository. main is fully free software. contrib and non-free contain packages with different licensing.

Distro Note: Ubuntu uses components named main, restricted, universe, and multiverse. Debian uses main, contrib, and non-free. The naming differs but the concept is the same.

Modern DEB822 Format

Newer Debian and Ubuntu releases are migrating to the DEB822 .sources format in /etc/apt/sources.list.d/:

Types: deb deb-src
URIs: http://deb.debian.org/debian
Suites: bookworm bookworm-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

This format is more readable and explicitly ties repositories to their signing keys.

Essential APT Commands

Update the package index (always do this first):

$ sudo apt update
Hit:1 http://deb.debian.org/debian bookworm InRelease
Get:2 http://security.debian.org/debian-security bookworm-security InRelease [48.0 kB]
Fetched 48.0 kB in 1s (42.3 kB/s)
Reading package lists... Done
Building dependency tree... Done
15 packages can be upgraded. Run 'apt list --upgradable' to see them.

Install a package:

$ sudo apt install nginx
Reading package lists... Done
Building dependency tree... Done
The following additional packages will be installed:
  libnginx-mod-http-geoip2 libnginx-mod-http-image-filter ...
The following NEW packages will be installed:
  libnginx-mod-http-geoip2 libnginx-mod-http-image-filter nginx nginx-common nginx-core
0 upgraded, 5 newly installed, 0 to remove and 15 not upgraded.
Need to get 1,847 kB of archives.
Do you want to continue? [Y/n]

Upgrade all installed packages:

$ sudo apt upgrade          # Safe upgrade: never removes packages
$ sudo apt full-upgrade     # May remove packages to resolve conflicts

Safety Warning: apt full-upgrade can remove packages. Always review what it proposes before confirming. On production servers, prefer apt upgrade and handle conflicts manually.

Search for packages:

$ apt search "web server"
nginx/stable 1.22.1-9 amd64
  small, powerful, scalable web/reverse proxy server

apache2/stable 2.4.57-2 amd64
  Apache HTTP Server

Show package details:

$ apt show nginx
Package: nginx
Version: 1.22.1-9
Depends: nginx-core (<< 1.22.1-9.1~) | nginx-full (<< 1.22.1-9.1~) ...
Description: small, powerful, scalable web/reverse proxy server

Remove a package:

$ sudo apt remove nginx          # Removes the package, keeps config files
$ sudo apt purge nginx           # Removes the package AND config files
$ sudo apt autoremove             # Removes orphaned dependencies

List installed packages:

$ apt list --installed
$ apt list --installed | grep nginx

dpkg: The Low-Level Tool

When you need to work with individual .deb files or query the package database directly:

# Install a local .deb file
$ sudo dpkg -i package.deb

# List all installed packages
$ dpkg -l

# List files installed by a package
$ dpkg -L nginx
/.
/usr
/usr/sbin
/usr/sbin/nginx
/usr/share/doc/nginx
...

# Find which package owns a file
$ dpkg -S /usr/sbin/nginx
nginx-core: /usr/sbin/nginx

# Show package status
$ dpkg -s nginx

When dpkg -i fails due to missing dependencies, fix it with:

$ sudo dpkg -i some-package.deb
dpkg: dependency problems prevent configuration of some-package:
 some-package depends on libfoo; however: Package libfoo is not installed.

$ sudo apt install -f    # Fix broken dependencies

PPAs (Ubuntu)

Personal Package Archives let developers distribute packages outside the official repositories. They are common on Ubuntu.

# Add a PPA
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt update
$ sudo apt install python3.12

Safety Warning: PPAs are not officially vetted. Only add PPAs from sources you trust. A malicious PPA could replace system packages with compromised versions.

To remove a PPA:

$ sudo add-apt-repository --remove ppa:deadsnakes/ppa
$ sudo apt update

APT Pinning

Sometimes you want to hold a package at a specific version or prefer packages from one repository over another. This is called pinning.

Hold a package at its current version:

$ sudo apt-mark hold nginx
nginx set on hold.

$ sudo apt upgrade
The following packages have been kept back:
  nginx

Release the hold:

$ sudo apt-mark unhold nginx

Install a specific version:

# List available versions
$ apt list -a nginx
nginx/stable 1.22.1-9 amd64
nginx/oldstable 1.18.0-6.1+deb11u3 amd64

# Install a specific version
$ sudo apt install nginx=1.22.1-9

For advanced pinning, create a file in /etc/apt/preferences.d/:

Package: nginx
Pin: version 1.22.1-9
Pin-Priority: 1001

Priority values: 1001 forces a downgrade if needed, 500 is the default, 100 means only install if no other version is available.


The DNF/YUM Ecosystem (Fedora/RHEL)

DNF (Dandified YUM) is the successor to YUM. On RHEL 8+ and Fedora 22+, dnf is the standard. On older systems (RHEL 7 and earlier), yum is used. The command syntax is nearly identical.

┌──────────────────────────────────────────┐
│  dnf (high-level package manager)        │
├──────────────────────────────────────────┤
│  libdnf / hawkey (dependency solver)     │
├──────────────────────────────────────────┤
│  rpm (low-level package installer)       │
└──────────────────────────────────────────┘

Repository Configuration

Repos are defined in /etc/yum.repos.d/ as .repo files:

$ cat /etc/yum.repos.d/fedora.repo
[fedora]
name=Fedora $releasever - $basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch

Key fields:

  • enabled: 1 (active) or 0 (disabled)
  • gpgcheck: 1 to verify package signatures (always leave this on)
  • gpgkey: Path to the GPG key for signature verification
  • baseurl or metalink: Where to find packages

Essential DNF Commands

# Update repository metadata
$ sudo dnf check-update

# Install a package
$ sudo dnf install nginx
Dependencies resolved.
===========================================================================
 Package              Arch        Version              Repository    Size
===========================================================================
Installing:
 nginx                x86_64      1:1.24.0-1.fc39      updates      42 k
Installing dependencies:
 nginx-core           x86_64      1:1.24.0-1.fc39      updates     589 k
 nginx-filesystem     noarch      1:1.24.0-1.fc39      updates      11 k

Transaction Summary
===========================================================================
Install  3 Packages

Total download size: 642 k
Is this ok [y/N]:

Upgrade packages:

$ sudo dnf upgrade               # Upgrade all packages
$ sudo dnf upgrade nginx          # Upgrade a specific package
$ sudo dnf upgrade --security     # Only security updates

Search and info:

$ dnf search "web server"
$ dnf info nginx
$ dnf provides /usr/sbin/nginx     # Find which package provides a file

Remove packages:

$ sudo dnf remove nginx
$ sudo dnf autoremove               # Remove unneeded dependencies

List packages:

$ dnf list installed
$ dnf list available
$ dnf list updates

Transaction history:

One of DNF's most powerful features -- every operation is recorded and can be undone:

$ dnf history
ID     | Command line              | Date and time    | Action(s)  | Altered
-------+---------------------------+------------------+------------+--------
    15 | install nginx              | 2024-03-15 10:22 | Install    |    3
    14 | upgrade                    | 2024-03-14 22:00 | Upgrade    |   28
    13 | remove httpd               | 2024-03-10 14:15 | Removed    |    5

# Undo a transaction
$ sudo dnf history undo 15    # Removes nginx and its dependencies

RPM: The Low-Level Tool

# Install a local .rpm file
$ sudo rpm -ivh package.rpm

# Query all installed packages
$ rpm -qa

# Query info about an installed package
$ rpm -qi nginx

# List files in an installed package
$ rpm -ql nginx

# Find which package owns a file
$ rpm -qf /usr/sbin/nginx
nginx-core-1.24.0-1.fc39.x86_64

# Verify package integrity (check if files have been modified)
$ rpm -V nginx
S.5....T.  c /etc/nginx/nginx.conf

The verification output tells you exactly what changed. The flags mean:

  • S: File size differs
  • 5: MD5 checksum differs
  • T: Modification time differs
  • c: This is a config file

DNF Modules (RHEL/CentOS Stream)

RHEL uses modules to provide multiple versions of software from the same repository:

$ dnf module list nodejs
Name    Stream   Profiles                      Summary
nodejs  18       common [d], development       Javascript runtime
nodejs  20       common [d], development       Javascript runtime

$ sudo dnf module enable nodejs:20
$ sudo dnf install nodejs

Version Locking with DNF

# Install the versionlock plugin
$ sudo dnf install python3-dnf-plugin-versionlock

# Lock a package
$ sudo dnf versionlock add nginx
Adding versionlock on: nginx-1:1.24.0-1.fc39.*

# List locked packages
$ sudo dnf versionlock list

# Remove a lock
$ sudo dnf versionlock delete nginx

Think About It: DNF records a full transaction history that can be undone. Why is this valuable on production servers? What could go wrong if an upgrade breaks something?


The Pacman Ecosystem (Arch Linux)

Pacman is Arch Linux's package manager. It is fast, simple, and does not try to do more than it needs to.

Essential Pacman Commands

Pacman uses single-letter flags. The main operations are:

  • -S: Sync (install/update from repositories)
  • -R: Remove
  • -Q: Query (local database)
  • -F: File query (which package provides a file)
# Synchronize package databases and upgrade all packages
$ sudo pacman -Syu
:: Synchronizing package databases...
 core                  130.4 KiB  1234 KiB/s 00:00
 extra                   8.7 MiB  5.32 MiB/s 00:02
 multilib              147.5 KiB  1567 KiB/s 00:00
:: Starting full system upgrade...
 there is nothing to do

# Install a package
$ sudo pacman -S nginx

# Search for a package
$ pacman -Ss "web server"
extra/nginx 1.24.0-1
    Lightweight HTTP server and IMAP/POP3 proxy server

# Show package info
$ pacman -Si nginx       # Remote info
$ pacman -Qi nginx       # Local (installed) info

# List files installed by a package
$ pacman -Ql nginx

# Find which package owns a file
$ pacman -Qo /usr/bin/nginx

# Remove a package and its unneeded dependencies
$ sudo pacman -Rsu nginx

# Remove a package, dependencies, and config files
$ sudo pacman -Rns nginx

Safety Warning: On Arch Linux, always run pacman -Syu (full system upgrade) before installing new packages. Partial upgrades (installing a package without upgrading) can break your system because Arch is a rolling release.

The AUR (Arch User Repository)

The AUR is a community-driven repository of build scripts (PKGBUILDs) for software not in the official repos. It is one of the largest software repositories on Linux.

Important: AUR packages are not officially vetted. You should always inspect the PKGBUILD before building.

Using makepkg manually:

# Install base-devel group (build tools)
$ sudo pacman -S --needed base-devel git

# Clone the AUR package
$ git clone https://aur.archlinux.org/yay.git
$ cd yay

# Inspect the build script
$ cat PKGBUILD

# Build and install
$ makepkg -si

Using an AUR helper (yay):

Once you have yay installed, it wraps pacman for both official and AUR packages:

$ yay -S some-aur-package
$ yay -Syu                    # Upgrade everything, including AUR packages

Pacman Configuration

Pacman is configured in /etc/pacman.conf:

[options]
HoldPkg     = pacman glibc
Architecture = auto
Color
CheckSpace
ParallelDownloads = 5

[core]
Include = /etc/pacman.d/mirrorlist

[extra]
Include = /etc/pacman.d/mirrorlist

Useful options:

  • ParallelDownloads: Download multiple packages simultaneously (significant speed improvement)
  • Color: Colorize output
  • IgnorePkg: Skip specific packages during upgrades (equivalent to version pinning)
# Pin/ignore a package
IgnorePkg = linux linux-headers

Comparing the Three Ecosystems

TaskAPT (Debian/Ubuntu)DNF (Fedora/RHEL)Pacman (Arch)
Update repo metadataapt updatednf check-updatepacman -Sy
Installapt install pkgdnf install pkgpacman -S pkg
Removeapt remove pkgdnf remove pkgpacman -R pkg
Remove + depsapt autoremovednf autoremovepacman -Rsu pkg
Upgrade allapt upgradednf upgradepacman -Syu
Searchapt search termdnf search termpacman -Ss term
Show infoapt show pkgdnf info pkgpacman -Si pkg
List filesdpkg -L pkgrpm -ql pkgpacman -Ql pkg
Find owner of filedpkg -S /pathrpm -qf /pathpacman -Qo /path
List installedapt list --installeddnf list installedpacman -Q
Pin/hold versionapt-mark hold pkgdnf versionlock add pkgIgnorePkg in conf
Clean cacheapt cleandnf clean allpacman -Sc

Cleaning Package Caches

Package managers cache downloaded packages. Over time, this can consume significant disk space.

# APT: See cache size, then clean
$ du -sh /var/cache/apt/archives/
847M    /var/cache/apt/archives/

$ sudo apt clean             # Remove ALL cached packages
$ sudo apt autoclean         # Remove only obsolete cached packages

# DNF: Clean metadata and packages
$ sudo dnf clean all
$ sudo dnf clean packages    # Only remove cached packages

# Pacman: Clean cache
$ sudo pacman -Sc            # Remove old cached packages (keeps current)
$ sudo pacman -Scc           # Remove ALL cached packages

Distro Note: On servers with automated updates, the package cache can grow to several gigabytes. Schedule periodic cache cleaning in a cron job or systemd timer.


Security Updates

Applying security patches quickly is critical for any system exposed to the internet.

APT: Security Updates Only

# List security updates
$ apt list --upgradable 2>/dev/null | grep -i security

# Install only security updates (Debian)
$ sudo apt upgrade -y -o Dir::Etc::SourceList=/etc/apt/sources.list \
    -o Dir::Etc::SourceParts=/dev/null \
    -t bookworm-security

# Ubuntu has unattended-upgrades for automatic security patches
$ sudo apt install unattended-upgrades
$ sudo dpkg-reconfigure -plow unattended-upgrades

DNF: Security Updates Only

$ sudo dnf upgrade --security
$ dnf updateinfo list security

Automatic Updates

For production servers, consider enabling automatic security updates:

# Debian/Ubuntu: unattended-upgrades
$ cat /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};

# Fedora/RHEL: dnf-automatic
$ sudo dnf install dnf-automatic
$ sudo systemctl enable --now dnf-automatic-install.timer

Safety Warning: Even automatic security updates carry risk. A kernel update requires a reboot. A library update could break an application. On critical production servers, test updates in a staging environment first.


Hands-On: Package Investigation Lab

Let us practice querying the package database. These exercises work on any distribution -- just use the appropriate commands from the comparison table above.

Exercise 1: Trace a binary to its package

# Step 1: Find the full path of a command
$ which curl
/usr/bin/curl

# Step 2: Find which package owns it
# Debian/Ubuntu:
$ dpkg -S /usr/bin/curl
curl: /usr/bin/curl

# Fedora/RHEL:
$ rpm -qf /usr/bin/curl
curl-8.2.1-1.fc39.x86_64

# Arch:
$ pacman -Qo /usr/bin/curl
/usr/bin/curl is owned by curl 8.5.0-1

Exercise 2: Examine package dependencies

# Debian/Ubuntu: Show what a package depends on
$ apt depends curl
curl
  Depends: libc6 (>= 2.34)
  Depends: libcurl4 (= 7.88.1-10+deb12u5)
  Depends: zlib1g (>= 1:1.1.4)

# And the reverse -- what depends on this package
$ apt rdepends curl

# Fedora/RHEL:
$ dnf repoquery --requires curl
$ dnf repoquery --whatrequires curl

# Arch:
$ pacman -Si curl | grep Depends
$ pacman -Qi curl | grep "Required By"

Exercise 3: Find packages that provide a specific file

# You need a file but don't know which package provides it
# Debian/Ubuntu:
$ apt-file search libssl.so
libssl-dev: /usr/lib/x86_64-linux-gnu/libssl.so
libssl3: /usr/lib/x86_64-linux-gnu/libssl.so.3

# (Install apt-file first: sudo apt install apt-file && sudo apt-file update)

# Fedora/RHEL:
$ dnf provides */libssl.so

# Arch:
$ pacman -F libssl.so

Debug This

A colleague reports that apt update is failing on a Debian server:

$ sudo apt update
Err:1 http://deb.debian.org/debian bookworm InRelease
  Could not resolve 'deb.debian.org'
Err:2 http://security.debian.org/debian-security bookworm-security InRelease
  Could not resolve 'security.debian.org'
Reading package lists... Done
W: Failed to fetch http://deb.debian.org/debian/dists/bookworm/InRelease
   Could not resolve 'deb.debian.org'
E: Some index files failed to download. They have been ignored, or old ones used instead.

What would you check?

  1. DNS resolution: Can the server resolve any hostname?

    $ nslookup deb.debian.org
    $ cat /etc/resolv.conf
    
  2. Network connectivity: Can you reach the internet at all?

    $ ping -c 3 8.8.8.8
    
  3. Proxy settings: Is the server behind a proxy?

    $ env | grep -i proxy
    

Now here is a different failure -- a colleague tries to install a package and gets:

$ sudo apt install libfoo-dev
E: Unable to locate package libfoo-dev

Checklist:

  1. Did you run sudo apt update first?
  2. Is the package name correct? (apt search libfoo)
  3. Is the package in a component that is not enabled? (Check universe on Ubuntu)
  4. Is the package only available for a different architecture?
  5. Has the package been renamed or replaced?

What Just Happened?

┌──────────────────────────────────────────────────────────────┐
│                                                               │
│  In this chapter, you learned:                                │
│                                                               │
│  - Package managers handle installation, dependency           │
│    resolution, updates, removal, and tracking.                │
│                                                               │
│  - APT (Debian/Ubuntu): apt/apt-get for high-level ops,      │
│    dpkg for low-level .deb manipulation, sources.list         │
│    for repository configuration.                              │
│                                                               │
│  - DNF (Fedora/RHEL): dnf for high-level ops, rpm for        │
│    low-level .rpm work, .repo files in /etc/yum.repos.d/.    │
│    Transaction history with undo capability.                  │
│                                                               │
│  - Pacman (Arch): Single tool with -S/-R/-Q/-F flags.        │
│    AUR for community packages. Rolling release requires       │
│    full-system upgrades.                                      │
│                                                               │
│  - Version pinning prevents unwanted upgrades.                │
│                                                               │
│  - Cache cleaning recovers disk space.                        │
│                                                               │
│  - Security updates should be prioritized and can be          │
│    automated with unattended-upgrades or dnf-automatic.       │
│                                                               │
│  - You can trace any file to its package, examine             │
│    dependencies, and find which package provides a file.      │
│                                                               │
└──────────────────────────────────────────────────────────────┘

Try This

Exercises

  1. Inventory exercise: List all installed packages on your system, sort them by installed size, and find the 10 largest. (Hint: on Debian/Ubuntu, try dpkg-query -W --showformat='${Installed-Size}\t${Package}\n' | sort -rn | head -10)

  2. Dependency tree: Pick a complex package (like firefox or nginx) and map out its dependency tree. How many packages does it pull in? (Hint: apt depends --recurse or dnf repoquery --requires --resolve --recursive)

  3. File hunt: Without installing it, find out what files the strace package would place on your system. (Hint: on Debian, use apt-file list strace; on Fedora, use dnf repoquery -l strace)

  4. Repository management: On a test system, add a third-party repository (like the Docker official repo), install a package from it, then cleanly remove both the package and the repository.

  5. Version pinning: On a test system, install a package, pin it to the current version, run a full upgrade, and confirm the pinned package was held back.

Bonus Challenge

Write a shell script that works on both Debian/Ubuntu and Fedora/RHEL systems. The script should detect which distribution it is running on (using /etc/os-release), then use the appropriate package manager to: update the package index, list available security updates, and report how many packages need updating. This is the kind of multi-distro script you will write in real operations work.


What's Next

You now know how to install software from repositories, but what do you do when the package you need is not available in any repository, or you need a newer version with custom options? Chapter 58 teaches you how to compile software from source code -- the original way of installing software on Unix and Linux.