Ubuntu tracks most desktop and server software as .deb packages managed by APT and dpkg. When you need a software inventory—for troubleshooting, migration, or cleanup—you usually want one of three things: the full list, a single package lookup, or a count or export you can reuse on another machine.
This guide is organized by what you are trying to find. I ran every command on Ubuntu 25.04 and kept real terminal output below so you can compare your system.
Tested on: Ubuntu 25.04 (Plucky Puffin); kernel 6.14.0-37-generic; amd64.
.deb packages only. Snap and Flatpak apps use separate commands (snap list, flatpak list). A full inventory on a typical desktop combines all three.
What do you want to find?
| Goal | Command or section |
|---|---|
Full list of installed .deb packages (default) |
apt list --installed |
| Check one package by name | Search a specific package |
| Classic table with descriptions | dpkg -l |
| How many packages are installed | Count installed packages |
| Packages with updates waiting | List upgradable packages |
| Packages you chose yourself (not auto-deps) | Manually installed packages |
| Snap applications | List Snap packages |
| Flatpak applications | List Flatpak apps |
| Save names to a file / clone to another PC | Export the package list |
| Largest packages by disk use | Packages by installed size |
| When something was installed (recent history) | Install history from logs |
| Graphical list (desktop) | Ubuntu Software GUI |
Prerequisites
- Ubuntu 22.04 LTS, 24.04 LTS, or newer (25.04 tested)—see check Ubuntu version.
- Terminal access (local or SSH).
- No
sudorequired for read-only listing commands;sudoonly if your user cannot read/var/log/dpkg.log.
Related guides: apt command, dpkg command, remove unused packages, remove obsolete packages.
List all .deb packages with apt
On current Ubuntu releases, apt list --installed is the most readable default. It shows the package name, suite (plucky on 25.04), version, architecture, and install state:
apt list --installedPipe through less when the list is long:
apt list --installed | lessThe first lines on the test host looked like this:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Listing...
7zip/plucky,now 24.09+dfsg-7 amd64 [installed,automatic]
accountsservice/plucky,now 23.13.9-7ubuntu1 amd64 [installed,automatic]
acl/plucky,now 2.3.2-2 amd64 [installed,automatic]
adduser/plucky,plucky,now 3.137ubuntu2 all [installed,automatic]Common tags in the last column:
| Tag | Meaning |
|---|---|
[installed] |
You (or an explicit apt install) chose this package |
[installed,automatic] |
Installed as a dependency of something else |
[installed,local] |
Installed from a local .deb file, not from a configured repository |
apt. For scripts, prefer dpkg-query or accept the warning and parse carefully—see Troubleshooting.
Search for a specific package
By exact or glob name with apt
apt list --installed nmapExample output:
nmap/plucky,now 7.95+dfsg-2 amd64 [installed]Glob patterns work—list every installed package whose name starts with linux-image:
apt list --installed 'linux-image*'Filter the full list with grep
apt list --installed 2>/dev/null | grep -i wiresharkOn the test host that returned wireshark, wireshark-common, and related libraries.
Detailed metadata with apt show
apt show nmapShows version, section, maintainer, and Installed-Size:
Package: nmap
Version: 7.95+dfsg-2
Installed-Size: 4,480 kB
...Status from the dpkg database
dpkg -l nmap
dpkg -s nmapdpkg -l prints a one-line table row; dpkg -s prints full control-file fields (similar depth to apt show).
List packages with dpkg -l
dpkg -l is the classic low-level list. Every line starts with a two-letter status code; ii means installed and configured:
dpkg -lHeader and sample rows:
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii nmap 7.95+dfsg-2 amd64 The Network Mapper
ii bash 5.2.37-2ubuntu5 amd64 GNU Bourne Again SHellFilter with grep:
dpkg -l | grep -i '^ii' | grep nmapPattern matching with dpkg-query:
dpkg-query -l 'nmap*'That listed both nmap and nmap-common on the test system.
Count installed packages
Quiet count with apt:
apt -qq list --installed 2>/dev/null | wc -lCount fully installed rows with dpkg:
dpkg -l | grep -c '^ii'Both returned 2580 on the test host.
dpkg-query -W | wc -l returned 2606 on the same machine because it also includes 26 packages in deinstall state (rc—removed but config files left). For “installed binaries only,” filter ^ii or use apt list --installed.
Alternative one-liner with package names only:
dpkg --get-selections | grep -w install | wc -lList upgradable packages
Refresh repository metadata first, then list packages with a newer version in your sources:
sudo apt update
apt list --upgradableSample lines from the test host:
alsa-ucm-conf/plucky-updates 1.2.12-1ubuntu1.4 all [upgradable from: 1.2.12-1ubuntu1.3]
fwupd/plucky-updates 2.0.13-1~25.04.1 amd64 [upgradable from: 2.0.7-1]Count pending upgrades:
apt -qq list --upgradable 2>/dev/null | wc -lThat returned 34 after apt update on the test system. An empty list right after a full sudo apt upgrade is normal.
List manually installed packages
APT distinguishes packages you explicitly installed from dependencies it pulled in automatically.
List packages marked manual:
apt-mark showmanualFirst lines on the test host:
alsa-base
alsa-utils
amavisd-new
anacron
apport-gtk
appstream
apt-config-icons-hidpi
apt-fileCount:
apt-mark showmanual | wc -lThat returned 324 manual packages versus 2580 total installed—most entries are automatic dependencies.
List automatic-only packages:
apt-mark showauto | headTo mark a dependency as manual (so apt autoremove will not drop it):
sudo apt-mark manual packagenameList Snap packages
Snaps are not in the apt database. Use:
snap listExample output:
Name Version Rev Tracking Publisher
firefox 152.0.3-1 8568 latest/stable/… mozilla**
core22 20260225 2411 latest/stable canonical**
desktop-security-center 0+git.25daa58 151 1/stable/… canonical**Omit the header and count apps (excluding base snaps like core22 if you prefer) with your own filter, or count all lines minus one:
snap list | tail -n +2 | wc -lList Flatpak apps
If Flatpak is installed:
flatpak listOn the test host flatpak was not installed (command not found). Install the tool first when you use Flatpak software:
sudo apt install flatpakThen flatpak list shows application IDs, branches, and origins separately from apt and Snap.
Export the package list to a file
All installed package names (replication)
Save one name per line:
dpkg-query -f '${binary:Package}\n' -W > ~/packages.txt
head ~/packages.txtExample:
7zip
accountsservice
acl
adduser
adwaita-icon-themeOn the test host the file had 2606 lines (includes rc config leftovers). For installed-only names:
dpkg-query -W -f='${binary:Package}\n' | while read p; do
dpkg-query -W -f='${Status}' "$p" 2>/dev/null | grep -q '^install ok installed' && echo "$p"
done > ~/packages-installed.txtA simpler approach most admins use—export manual packages only:
apt-mark showmanual > ~/manual-packages.txtCopy the list to another Ubuntu machine
- Copy
manual-packages.txtorpackages.txtto the target system. - Enable the same PPAs and third-party
sources.list.dentries. - Install:
xargs -a manual-packages.txt sudo apt installExact versions will not match unless releases and repos align—treat the file as a checklist, not a byte-for-byte clone. For obsolete or leftover packages after a release upgrade, see remove obsolete packages on Ubuntu.
Export from apt (human-readable)
apt list --installed 2>/dev/null > ~/apt-installed.txtFind the largest installed packages
dpkg-query exposes Installed-Size in kilobytes:
dpkg-query -Wf '${Package}\t${Installed-Size}\n' | sort -n -k2 | tail -8With readable megabytes:
dpkg-query -Wf '${Package}\t${Installed-Size}\n' | sort -n -k2 | tail -8 | awk '{printf "%s\t%.1f MB\n", $1, $2/1024}'Largest entries on the test host:
libllvm20 154.6 MB
ubuntu-wallpapers-plucky 159.7 MB
openjdk-21-jre-headless 193.7 MB
nodejs 225.3 MB
kotlin 281.0 MB
llvm-20-dev 369.0 MB
google-chrome-stable 402.0 MB
linux-firmware 552.1 MBList packages over 100 MB:
dpkg-query -Wf '${Package}\t${Installed-Size}\n' | awk '$2 > 102400 {printf "%s\t%.1f MB\n", $1, $2/1024}'Package install history from logs
Logs are partial—rotated and truncated—but they answer “when was this installed recently?”
dpkg.log (per-package install lines)
grep " install " /var/log/dpkg.log | tail -5Recent lines on the test host:
2026-06-28 23:21:42 install libwiretap15:amd64 <none> 4.4.5-1
2026-06-28 23:21:43 install libwireshark18:amd64 <none> 4.4.5-1
2026-06-28 23:21:44 install wireshark-common:amd64 <none> 4.4.5-1
2026-06-28 23:21:45 install wireshark:amd64 <none> 4.4.5-1
2026-06-28 23:22:32 install tshark:amd64 <none> 4.4.5-1Archived logs:
zgrep " install " /var/log/dpkg.log.*.gz | tail -5Extract package names only:
grep " install " /var/log/dpkg.log | awk '{print $4}' | cut -d: -f1apt history (whole apt sessions)
less /var/log/apt/history.logShows Start-Date, Commandline, and grouped Install: lines—for example a apt-get install wireshark block with every dependency listed.
apt and apt-get, install multiple packages in one command, or pass flags before package names. Use logs as a hint, not a complete inventory.
Graphical list (Ubuntu Software)
On Ubuntu Desktop with GNOME:
- Open Activities and launch Ubuntu Software (or App Center on newer images).
- Open the Installed tab.
You can search, open details, and remove GUI applications from there. The view covers Snap and some .deb apps exposed to the store—it does not replace apt list for servers or a full package audit.
Optional: aptitude (legacy TUI)
aptitude is an older interactive front-end. It is not installed by default on Ubuntu 25.04:
sudo apt install aptitude
aptitude search '~i'Search installed Apache-related packages:
aptitude search '~i apache'Most administrators today use apt and dpkg directly; install aptitude only if you prefer its TUI or already rely on its search patterns.
Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
apt list WARNING in scripts |
Documented unstable CLI | Use dpkg-query -W or dpkg -l; redirect stderr: 2>/dev/null |
apt list empty or very short |
Wrong flag or typo | Use --installed (two dashes), not -installed |
| Count differs between tools | rc configs or non-ii states |
Use dpkg -l | grep '^ii' or apt list --installed for active packages |
| Package missing from apt list but app runs | Installed via Snap/Flatpak/binary | Run snap list, flatpak list, or which appname |
snap list shows only bases |
No user snaps installed yet | Install an app with snap install or check GUI store |
flatpak: command not found |
Flatpak not installed | sudo apt install flatpak or skip if you do not use Flatpak |
| Log grep misses old installs | Log rotation | Try zgrep on /var/log/dpkg.log.*.gz and /var/log/apt/history.log.*.gz |
dpkg -l shows rc |
Package removed, configs remain | sudo apt purge packagename—see remove unused packages |
References
- apt(8) — Ubuntu man page
- dpkg-query(1) — Ubuntu man page
- Package management — Ubuntu Server documentation
- snap(8) — Ubuntu man page
- apt-mark(8) — Ubuntu man page
Summary
For everyday use on Ubuntu, start with apt list --installed for the full .deb inventory and apt list packagename --installed or apt show when you care about one package. dpkg -l and dpkg-query remain the right tools for scripts, status codes, and disk-size reports. Add snap list (and flatpak list when relevant) so you do not miss applications outside apt.
When you need counts, apt -qq list --installed | wc -l and dpkg -l | grep -c '^ii' agreed at 2580 packages on the test host. Export apt-mark showmanual or a dpkg-query name list when you migrate to another machine, and use apt list --upgradable after sudo apt update to see pending updates. Log files under /var/log/dpkg.log and /var/log/apt/history.log help with recent install timing, not a complete lifetime inventory.

