Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Querying Ubuntu Packages with APT and dpkg

Hello, and welcome to the first lesson in the package-management portion of your LFCS preparation. This module builds the habits needed to make safe package decisions on Ubuntu: first inspect what is available and what is installed, then later manage repositories, perform controlled upgrades and removals, validate provenance, and recover from failures.

In this lesson, the focus is deliberately observational. You will learn to answer four operational questions without changing the system:

  1. What package provides this software or file?
  2. What files did an installed package place on the system?
  3. What version is installed, what version is available, and what would APT choose?
  4. What metadata and status does Ubuntu record for a package?

Two views of package information

Ubuntu is built on Debian package technology. Two tools matter here, but they look at different layers of information:

  • dpkg is the local package database tool. It knows what this machine has installed or recorded in its package-status database, and it can inspect a local .deb archive.
  • APT is the repository-aware layer. It uses locally cached package indexes from configured repositories to search available packages, show repository metadata, and determine a candidate version.

A useful way to frame this for troubleshooting is:

Question Primary tool
Is package bash installed, and what is its installed status? dpkg
Which package owns /usr/bin/ssh? dpkg
What files did openssh-client install? dpkg
Which packages matching “DNS server” are available from repositories? apt search
What dependencies and description does the repository publish for a package? apt show
What version is installed versus the version APT would select? apt-cache policy

APT’s answers depend on its local package index cache, generally built from the repository definitions under /etc/apt/. Running sudo apt update downloads refreshed index metadata. It does not install or upgrade packages; it merely refreshes APT’s view of what the configured sources offer.

5.4. Manipulating Packages with dpkg

Read the Debian Handbook's explanation of the boundary between dpkg and APT, then its compact reference for querying the local package database. This is the core reference for LFCS-style file ownership and installed-package questions.

First, before Section 5.4.1, read the tool roles. Focus on why dpkg is authoritative for local installation records while APT works with available packages and dependencies. Then navigate to Section 5.4.3, “Querying dpkg's Database and Inspecting .deb Files.” Read the query options, including the command meanings for -L, -S, -s, and -l. Skim Example 5.5 immediately below it to connect each option to realistic output. Finally, read the caution beginning “dpkg --search and merged /usr,” especially the merged usr caveat. On modern Ubuntu systems, a visible path and the path stored in the dpkg database can differ.


Querying repository metadata with APT

Start with apt when the question concerns software that may be available but is not necessarily installed.

Searching by purpose or name

apt search dns server

apt search searches package names and descriptions in APT’s current local indexes. It is useful when you know the function you need but not the exact package name. Search results can be broad, so refine terms rather than assuming the first result is correct.

For a narrower name-oriented check:

apt list 'nginx*'

Quote the pattern so the shell does not expand it before APT receives it. apt list shows versions known to APT; it is not limited to installed packages.

To list installed packages matching a pattern:

apt list --installed 'nginx*'

APT may print a warning that its command-line interface is not stable for scripts. That warning matters: use apt interactively, but use more deliberate tools and explicit output formats when scripting.

Showing available package metadata

Once you know a package name, use:

apt show nginx

Typical fields include:

  • package name and version
  • package description
  • dependencies, recommendations, and conflicts
  • architecture
  • installed and download sizes
  • package source and repository origin

This is repository-facing metadata. If several versions are available from your configured sources, apt show may show more than one record. Therefore, it is excellent for investigation, but it is not by itself the clearest answer to “what will APT install?”

Installed, candidate, and available versions

Use apt-cache policy when version selection matters:

apt-cache policy nginx

A representative structure is:

nginx:
  Installed: 1.24.0-2ubuntu7
  Candidate: 1.24.0-2ubuntu7.1
  Version table:
     1.24.0-2ubuntu7.1 500
        500 http://archive.ubuntu.com/... Packages
 *** 1.24.0-2ubuntu7 100
        100 /var/lib/dpkg/status

Interpret the main fields precisely:

  • Installed is the version recorded as installed locally. It can be (none).
  • Candidate is the version APT would normally select if you requested an installation or upgrade under the current source and preference configuration.
  • Version table lists known versions and their sources.
  • The *** marks the installed version.
  • The numbers are APT priorities. You do not need to memorize every priority rule yet, but you should recognize that a higher version is not always automatically the candidate.

Run policy without a package name when investigating the overall configured sources and their priorities:

apt-cache policy

This becomes especially important in the next lesson, where repository configuration and source priority are the focus.

6.3. The apt-cache Command

Read the Debian Handbook's explanation of APT's local cache and its apt-cache policy output. It clarifies why package queries can be accurate yet stale, and how to distinguish an installed version from APT's candidate version.

In Section 6.3, read the opening explanation of the local cache, beginning with the cache rationale. Focus on the relationship between apt update, repository indexes, and search results. Then continue to Section 6.3.1, “The apt-cache policy Command.” Read from the policy example. Do not attempt to configure pinning yet; identify the Installed, Candidate, version-table, source, and priority information in the example.


Querying the local package database with dpkg

APT tells you what repositories advertise. dpkg tells you what the local system records.

For a reliable practice target, use bash: it should exist on a normal Ubuntu system, and its files and metadata are familiar.

List package records and read their status

dpkg -l bash

The beginning of a typical matching line is:

ii  bash  5.x...  amd64  GNU Bourne Again SHell

The first two characters are important:

  • The first i means the desired state is install.
  • The second i means the actual state is installed.

Thus, ii is the normal healthy state for an installed package. dpkg -l can also show packages that are no longer installed but still have residual configuration files. That is why it is better understood as a list of packages known to dpkg, not simply “all installed packages.”

For a specific package’s detailed local status record:

dpkg -s bash

Look especially for:

Status: install ok installed
Version: ...
Architecture: ...
Depends: ...
Conffiles:

dpkg -s is a strong diagnostic command because it answers both “is it installed?” and “what package metadata does the local database have for it?”

For concise, script-friendly version and state output, use dpkg-query:

dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version}\n' bash

This command is useful in administrative scripts because you explicitly choose the fields rather than parsing human-oriented columns.

List every file installed by a package

dpkg -L bash

This lists paths registered as installed by bash, including executables, documentation, shell startup files, and directories. To inspect a long list efficiently:

dpkg -L bash | less

A package’s file list is valuable when:

  • confirming where a binary or configuration file came from;
  • checking whether a package ought to contain an expected file;
  • distinguishing package-managed files from locally created files;
  • planning a change without blindly deleting files.

For example, dpkg -L openssh-server helps establish which files were supplied by the server package before you investigate local modifications in /etc/ssh/.

Find which package owns a path

Reverse the question with dpkg -S:

dpkg -S /etc/bash.bashrc

A typical result is:

bash: /etc/bash.bashrc

This means that the dpkg database records bash as the package that owns that path.

Other practical examples:

dpkg -S /usr/bin/ssh
dpkg -S /usr/bin/systemctl
dpkg -S /usr/bin/apt

This is a high-value LFCS troubleshooting pattern. If a command behaves unexpectedly, first identify its package owner; then inspect that package’s installed version and metadata.

There are important boundaries:

  • dpkg -S identifies database ownership, not whether the file is currently present, unmodified, or functional.
  • A manually created file normally has no package owner.
  • A file created dynamically by a service, such as a PID file or log file, often has no package owner.
  • A symlink may have a different owner from its final target.
  • On merged-/usr systems, /bin, /sbin, and /lib may be symlinks into /usr. The package database may record one path while you typed another.

If a lookup fails for a path that clearly exists, inspect the path first:

readlink -f /bin/bash
dpkg -S /bin/bash /usr/bin/bash 2>/dev/null

Do not treat a failed ownership lookup as proof that the file is untrusted or manually installed. First account for symbolic links and the path form recorded by the package.


Inspecting a downloaded .deb without installing it

A .deb file is a package archive. dpkg can inspect it without changing the system:

dpkg -I /path/to/package.deb

The uppercase -I displays archive control metadata: package name, version, architecture, dependencies, description, and maintainer scripts.

To list the payload paths that would be installed:

dpkg -c /path/to/package.deb

The lowercase -c shows archive contents, not files presently installed on your machine.

Keep the distinction clear:

Question Command
What files did the locally installed package register? dpkg -L package
Which installed package owns this path? dpkg -S /path/to/file
What metadata does the local status database record? dpkg -s package
What files would this uninstalled .deb archive place? dpkg -c file.deb
What metadata is inside this .deb archive? dpkg -I file.deb

A repeatable package-investigation routine

When given a package or a suspicious path in an exam task or a real incident, work through the question in a controlled order.

For a package named PACKAGE:

apt show PACKAGE
apt-cache policy PACKAGE
dpkg -s PACKAGE
dpkg -L PACKAGE

For a path named PATH:

dpkg -S PATH

Then investigate the identified package:

dpkg -s PACKAGE
dpkg -L PACKAGE
apt-cache policy PACKAGE

This workflow separates three facts that are easy to confuse:

  1. Repository availability: what APT knows from configured sources.
  2. APT selection: which version APT considers the candidate.
  3. Local installation state: what dpkg records as installed and which paths it owns.

Avoid changing package state just to answer an inventory question. All the commands above are read-only, except apt update, which refreshes APT indexes but still does not install or remove software.


You should now be able to distinguish APT’s repository view from dpkg’s local-system view, identify package ownership, list package-managed files, and explain installed versus candidate versions. These are the inspection skills that make package administration predictable rather than trial-and-error.

Next, you will configure an APT repository using scoped signing-key trust and verify how its source priority affects package selection.

Can't find a good explanation? Sign up and we'll make it for you

Sign up