Package management is the single skill that separates someone who uses Ubuntu from someone who truly runs it. This page is your practical reference for apt, apt-get, pinned packages, common flags, and the day-to-day terminal patterns that keep an Ubuntu system healthy โ drawn from over a decade of managing everything from personal desktops to fleets of headless servers. We’ll cover the update/upgrade cycle, the real differences between apt and apt-get, how to hold packages at a specific version, and the pitfalls that trip up newcomers and veterans alike. If you’re looking for the broader documentation section, start at our Documentation hub.
apt Basics: install, remove, search, update, upgrade
Everything starts with the package index. Before you install or upgrade anything, refresh it:
sudo apt update
That command talks to every repository in /etc/apt/sources.list and /etc/apt/sources.list.d/ and pulls down the current package listings. It doesn’t change anything on your system โ it just updates what apt knows about.
Installing a package is exactly what you’d expect:
sudo apt install vim
Want to install a specific version? Append the version string:
sudo apt install vim=2:9.0.1000-4ubuntu2
Removing a package:
sudo apt remove vim
That leaves config files behind. If you want everything gone โ package files and configuration:
sudo apt purge vim
Searching the package index:
apt search "text editor"
For a tighter listing when you know the exact name:
apt list --installed | grep vim
Upgrading all installed packages:
sudo apt upgrade
This upgrades every package it can without removing anything or pulling in brand-new dependencies. When packages require new dependencies or removals, apt upgrade holds them back. That’s where full-upgrade comes in:
sudo apt full-upgrade
Use full-upgrade for point releases and kernel jumps. For routine daily updates, plain upgrade is safer.
apt vs apt-get: When to Use Which
Here’s the short version: use apt when you’re typing commands interactively; use apt-get and apt-cache in scripts, cron jobs, and Dockerfiles.
Why? apt was introduced in Ubuntu 14.04 as a friendlier front end. It merges functionality from apt-get, apt-cache, and apt-mark into a single command, adds a progress bar, and color-codes output. It’s genuinely nicer to use at a terminal prompt. But its output format isn’t considered a stable API โ the Debian team reserves the right to change how apt displays information between releases. Scripts that parse apt output can break silently after a dist-upgrade.
apt-get output, on the other hand, has been stable for decades. If you’re writing a provisioning script, a CI pipeline, or anything that will run unattended, reach for apt-get install -y and apt-cache search. Your future self will thank you. For a more detailed breakdown of the apt and apt-get ecosystem, the Ubuntu Community Help Wiki is an excellent reference maintained by the community.
Practically speaking, the commands map almost one-to-one:
Interactive (apt) | Scripting (apt-get / apt-cache) |
|---|---|
apt install | apt-get install |
apt remove | apt-get remove |
apt update | apt-get update |
apt upgrade | apt-get upgrade |
apt full-upgrade | apt-get dist-upgrade |
apt search | apt-cache search |
apt show | apt-cache show |
Note the full-upgrade / dist-upgrade naming difference. Same operation, different label.
Pinned Packages and Hold
Sometimes you need a package to stay put. Maybe a kernel update broke your Nvidia driver last time. Maybe your application depends on a specific library version. That’s what package holds are for.
Mark a package as held:
sudo apt-mark hold linux-image-generic
Verify what’s held:
apt-mark showhold
Release the hold when you’re ready:
sudo apt-mark unhold linux-image-generic
Held packages will not be upgraded by apt upgrade or apt full-upgrade. They show up in the “kept back” list as a reminder.
For more granular control โ say, you want to pin a package to a specific repository or version range โ edit /etc/apt/preferences.d/. A pin file looks like this:
Package: firefox
Pin: version 115.*
Pin-Priority: 1001
A priority above 1000 forces that version even if it means downgrading. Be careful with this โ it’s a sharp tool. Most of the time, apt-mark hold is all you need.
Useful Flags and Patterns
A handful of flags make daily work noticeably smoother.
Dry run โ see what would happen without changing anything:
sudo apt install --dry-run nginx
Reinstall โ force a fresh install of a package (useful when config files get corrupted):
sudo apt install --reinstall openssh-server
Download only โ grab .deb files without installing:
sudo apt install --download-only build-essential
The files land in /var/cache/apt/archives/. Speaking of that directory: it grows forever unless you clean it. Free the space:
sudo apt clean
Or keep only the latest cached version of each package:
sudo apt autoclean
Autoremove โ clean up packages that were pulled in as dependencies but are no longer needed:
sudo apt autoremove
This one is safe to run regularly. It respects holds and manual install marks.
Common Pitfalls
Running upgrade without update first. You’ll get zero upgrades and wonder why. Always update then upgrade. Every time.
Forgetting about dpkg locks. If apt crashes or you close a terminal mid-install, you might see Could not get lock /var/lib/dpkg/lock-frontend. The temptation is to delete the lock file manually. Don’t โ at least not immediately. First check whether another apt or dpkg process is still running (ps aux | grep -E 'apt|dpkg'). If it is, let it finish. If it’s truly dead, then remove the lock:
sudo rm /var/lib/dpkg/lock-frontend
sudo rm /var/lib/dpkg/lock
sudo dpkg --configure -a
Mixing PPAs carelessly. Third-party PPAs can overwrite official packages with untested versions. Before adding a PPA, check what packages it provides (apt policy package-name after adding). Remove PPAs you no longer need with sudo add-apt-repository --remove ppa:owner/name.
Ignoring held-back packages forever. Those “kept back” messages during apt upgrade aren’t just noise. They often indicate a pending kernel or critical library update that requires full-upgrade to land. Ignoring them for months leaves your system in a weird partial-upgrade state that gets harder to untangle over time.
Purging when you meant to remove. apt purge deletes configuration files system-wide. If you purge a database server, its config (and sometimes data directory references) go with it. Use remove first, verify you don’t need the configs, then purge if you want a truly clean slate.
Related Reading
Check the front matter of this page for internal links to related Ubuntu Portal documentation, including our guides on filesystems and mounts, and the broader documentation hub.
