dpkg is the low-level package tool underneath apt on Debian and Ubuntu. Day to day you use apt, but dpkg is what you need to inspect installed packages, find which package owns a file, install a downloaded .deb, or recover from an interrupted upgrade.

dpkg vs apt

  • apt downloads packages from repositories and resolves dependencies automatically.
  • dpkg installs, removes and queries local .deb files. It doesn’t fetch dependencies.

See apt commands for the high-level tool.

Install a .deb file

The best way is to let apt handle the dependencies:

sudo apt install ./package.deb

The ./ matters: it tells apt this is a file, not a package name.

With dpkg directly:

sudo dpkg -i package.deb
sudo apt -f install          # pull in any missing dependencies

List installed packages

dpkg -l                       # all packages
dpkg -l | grep nginx          # filter
dpkg -l 'php8.3*'             # by pattern

The first column shows the state. ii means installed and OK. rc means removed, but config files remain. iU and iF mean an unpacked or half-configured package, which is a problem.

Clean up rc leftovers:

dpkg -l | awk '/^rc/ {print $2}' | xargs -r sudo dpkg --purge

Is one package installed, and which version?

dpkg -s nginx | grep -E 'Status|Version'
dpkg-query -W -f='${Version}\n' nginx

Which package owns this file?

dpkg -S /usr/sbin/nginx
# nginx-core: /usr/sbin/nginx

dpkg -S bin/convert           # partial paths work too

To search files in packages you haven’t installed, use apt-file: sudo apt install apt-file && sudo apt-file update && apt-file search bin/convert.

What files does a package contain?

dpkg -L nginx-core            # installed package
dpkg -c package.deb           # contents of a .deb file
dpkg -I package.deb           # package metadata (version, dependencies)

Remove and purge

sudo dpkg -r package          # remove, keep config files
sudo dpkg -P package          # purge: remove including config files

apt remove and apt purge are usually better, because they also handle reverse dependencies.

Fix “dpkg was interrupted”

E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.

An upgrade was cut off: the SSH session dropped, a reboot happened or the disk filled up. Run:

sudo dpkg --configure -a
sudo apt -f install
sudo apt update && sudo apt upgrade

Run long upgrades inside tmux so a dropped connection doesn’t interrupt them. See tmux.

Fix “Could not get lock /var/lib/dpkg/lock-frontend”

Another process is using dpkg, usually automatic updates (unattended-upgrades) running after boot:

ps aux | grep -E 'apt|dpkg' | grep -v grep

Wait for it to finish. Don’t delete the lock files while a process holds them. That’s how databases of installed packages get corrupted. Only if no apt or dpkg process exists and the lock is stale:

sudo rm /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock
sudo dpkg --configure -a

More in apt update errors.

Broken package or failed post-install script

dpkg: error processing package foo (--configure):
 installed foo package post-installation script subprocess returned error exit status 1

The package’s maintainer script failed. Often a service didn’t start because of a config error. Read the output above the error, check journalctl -xe, fix the cause (a config typo, a port already in use, a full disk), then run sudo dpkg --configure -a again.

Hold a package at its current version

sudo apt-mark hold nginx           # preferred
echo "nginx hold" | sudo dpkg --set-selections
apt-mark showhold
sudo apt-mark unhold nginx

Held packages are skipped by apt upgrade. Use this for software you upgrade deliberately, like database servers or kernels, and remember to release the hold.

Reconfigure a package

Rerun a package’s setup questions:

sudo dpkg-reconfigure tzdata
sudo dpkg-reconfigure locales
sudo dpkg-reconfigure unattended-upgrades

Config file prompts during upgrades

When you’ve changed a config file and the package ships a new version, dpkg asks what to do. Press D to see a diff. Keeping your version (the default, N) is usually right. The package’s new version is saved as *.dpkg-dist. To answer non-interactively:

sudo apt -o Dpkg::Options::="--force-confold" upgrade -y

Quick reference

Task Command
Install .deb sudo apt install ./file.deb
List dpkg -l
Package status dpkg -s pkg
Owner of file dpkg -S /path
Files in package dpkg -L pkg
Fix interrupted sudo dpkg --configure -a
Purge sudo dpkg -P pkg
Hold version sudo apt-mark hold pkg

Related: snap packages and PPAs.

  • Linux
  • Debian
  • Ubuntu