apt-cache
Search and inspect packages without installing them
apt-cache answers questions about packages without changing any of them. Everything it knows
came out of the last apt update, so its queries need neither the network nor root. Most of what
it can describe is software this machine has never had.
Which version you would get
apt-cache policy <package> prints what is installed now and what apt install would fetch. If
those two lines differ, an upgrade is available and nobody has applied it. A candidate of
(none) means apt has the name and no version to go with it, which is the failure behind
"Package has no installation candidate".
Under them comes the version table, one line per version apt can see. Each carries the priority
that ranked it and the repository it came from, and the entry at priority 100 pointing to
/var/lib/dpkg/status is whatever is installed. Read the table when a machine is being offered
something you did not expect. The answer is usually a repository someone added, and
third-party repositories covers pinning one back down.
What the cache holds, and when it was filled
apt update fetches the repository indexes into /var/lib/apt/lists/, and apt compiles those
into the index apt-cache reads. Nothing here goes near the network, so the answers are as old
as that update: a package apt-cache claims not to know about is usually a machine that has not
run apt update since the archive moved.
Describing a package is not evidence of having it. apt-cache show will print the full record
for something dpkg -s has never heard of.
apt-cache or apt
apt search and apt show are the same queries with the output laid out for reading, and at a
prompt they are usually what you want. apt-cache is the one to call from a script, for the
reason apt vs apt-get goes into: apt's command-line interface is not
stable between versions, so it shouldn't be relied upon in a script. It will print a warning to
remind you.
What it cannot tell you
dpkg -S names the package a file on disk came from, out of what dpkg
recorded when it unpacked it. That only reaches packages you have installed. For a file you do
not have yet, apt-file search answers the same question, and the command
is not installed by default. Installing the apt-file package also adds the archive's Contents
index to what apt update fetches, so the sequence is install, update, then search.
Sample files used on this page
Every example below was run against these files. Recreate them to follow along.
/etc/apt/sources.list.d/vendor.sources the sandbox has a second repository configured alongside Debian's, which is what the version tables below are reading. It carries two packages: hello-tips, which Debian does not have at all, and a bash-completion at version 1:99.0-1, higher than the one Debian ships. Trusted: yes is there because this one is unsigned and local; a repository reached over the network wants Signed-By instead, which third-party repositories covers.
Types: deb
URIs: file:/srv/vendor
Suites: stable
Components: main
Trusted: yes
which of the page's packages are installed
ii bash-completion 1:2.16.0-7
ii cowsay 3.03+dfsg2-8
Which version would I get
apt-cache policy answers that whenever a package is not the version you expected. Installed is what is on the machine now and Candidate is what apt install would fetch, and the two lines together answer most of the question on their own.
Check what is installed and what apt would install
apt-cache policy cowsay | head -3
The two lines agreeing means the machine already has the version apt would choose, so there is nothing to upgrade. No root and no network: this reads the cache apt update last filled.
Show output
cowsay:
Installed: 3.03+dfsg2-8
Candidate: 3.03+dfsg2-8
See which version you would get before installing
apt-cache policy cowsay-off | head -3
(none) in the Installed line means the package is not on the machine. The Candidate line is what would arrive if you ran apt install cowsay-off, which is worth knowing before you agree to it.
Show output
cowsay-off:
Installed: (none)
Candidate: 3.03+dfsg2-8
Find out whether an upgrade is waiting
apt-cache policy bash-completion | head -3
The two lines disagreeing means an upgrade is available and not yet applied. Here the candidate comes from a repository other than Debian's, which the version table below these lines spells out.
Show output
bash-completion:
Installed: 1:2.16.0-7
Candidate: 1:99.0-1
Read the whole version table
apt-cache policy hello-tips
Under the first two lines, one entry per version apt can see. Each is followed by its priority, which is what decides the winner, and the indented line beneath names the repository the version came from.
Show output
hello-tips:
Installed: (none)
Candidate: 1.0-1
Version table:
1.0-1 500
500 file:/srv/vendor stable/main all Packages
Find out which repository a version is coming from
apt-cache policy bash-completion | head -6
The diagnostic to run when a package sits at a version you did not expect. A second repository is offering a higher version than Debian at the same priority, so it wins, and Debian's own entry follows below the six lines shown. See third-party repositories for how to stop that happening.
Show output
bash-completion:
Installed: 1:2.16.0-7
Candidate: 1:99.0-1
Version table:
1:99.0-1 500
500 file:/srv/vendor stable/main all Packages
Recognise a package with no installation candidate
apt-cache policy default-mta
A Candidate of (none) and an empty version table means apt knows the name but has no version to offer. Here it is a virtual package, a name real packages claim rather than one of their own. The same output appears when a package has been dropped from the archive.
Show output
default-mta:
Installed: (none)
Candidate: (none)
Version table:
Ask about several packages at once
apt-cache policy cowsay cowsay-off | grep -E '^[a-z]|: '
Every name you pass gets its own stanza. Dropping the version tables with grep fits a whole set of packages into a few lines.
Show output
cowsay:
Installed: 3.03+dfsg2-8
Candidate: 3.03+dfsg2-8
cowsay-off:
Installed: (none)
Candidate: 3.03+dfsg2-8
Notice that an unknown package name says nothing
apt-cache policy nosuchpackage; echo "exit $?"
No output and a success exit status, which is the trap on this command. A typo in a package name looks exactly like a package apt has nothing to say about, so never take a silent policy as confirmation the name was right.
Show output
exit 0
Pull the candidate version into a variable
V=$(apt-cache policy cowsay-off | awk '/Candidate:/ {print $2}'); echo "would install $V"
The field-per-line format is stable enough to parse, which is what apt-cache is for in a script where apt would print a warning. See Variables and quoting.
Show output
would install 3.03+dfsg2-8
Report whether a package is up to date
apt-cache policy bash-completion | awk '/Installed:/{i=$2} /Candidate:/{c=$2} END{ if (i==c) print "up to date"; else print "upgrade available: " i " -> " c }'
Comparing the two fields as strings, rather than trying to work out which version is newer. apt has already decided that; the candidate is by definition what it would install.
Show output
upgrade available: 1:2.16.0-7 -> 1:99.0-1
List the repositories apt is reading from
apt-cache policy | head -5
With no package named, policy prints the sources themselves and the priority each carries. /var/lib/dpkg/status at 100 is what is already installed, which is why an installed version is never silently replaced by an equal-priority one.
Show output
Package files:
100 /var/lib/dpkg/status
release a=now
500 file:/srv/vendor stable/main all Packages
release o=ExampleVendor,a=stable,n=stable,c=main,b=all
Show where a version lives and where it came from
apt-cache madison hello-tips
madison is the version table in one line per version, named after the Debian archive tool whose output it imitates. Handy when you want the answer on a single line rather than in a stanza.
Show output
hello-tips | 1.0-1 | file:/srv/vendor stable/main all Packages
Report the candidate version for a list of packages
for pkg in cowsay cowsay-off hello-tips; do printf '%s %s\n' "$pkg" "$(apt-cache policy "$pkg" | awk '/Candidate:/{print $2}')"; done
policy takes several names at once, but a loop keeps each answer on its own line and lets you format it. See Loops.
Show output
cowsay 3.03+dfsg2-8
cowsay-off 3.03+dfsg2-8
hello-tips 1.0-1
Reading a package's record
apt-cache show prints the stanza the repository publishes about a package, which is the same information dpkg -s gives for an installed one. The difference is that this works for packages you have never installed.
Read a package's description and metadata
apt-cache show cowsay | head -8
Everything the archive says about the package, one field per line. apt show prints the same record with the layout rearranged for reading.
Show output
Package: cowsay
Version: 3.03+dfsg2-8
Installed-Size: 92
Maintainer: James McDonald <james@jamesmcdonald.com>
Architecture: all
Depends: libtext-charwidth-perl, perl:any
Suggests: filters, cowsay-off
Description: configurable talking cow
Pick out just the fields you care about
apt-cache show cowsay | grep -E '^(Version|Installed-Size|Depends)'
Installed-Size is in kilobytes and is the archive's estimate of what the package will occupy once unpacked, which is not the size of the download.
Show output
Version: 3.03+dfsg2-8
Installed-Size: 92
Depends: libtext-charwidth-perl, perl:any
See a dependency's version constraints
apt-cache show cowsay-off | grep -E '^(Depends|Breaks|Replaces)'
The version ranges that apt-cache depends leaves out. Breaks and Replaces naming the same package as Depends is how a split package tells apt that older copies must go.
Show output
Replaces: cowsay (<< 3.03+dfsg2-3)
Depends: cowsay (>= 3.03+dfsg2-3)
Breaks: cowsay (<< 3.03+dfsg2-3)
Find the file apt would download
apt-cache show cowsay | grep -E '^(Filename|Size|SHA256)'
The path within the repository, the size of the .deb in bytes, and the checksum apt verifies after fetching it. Filename is relative to the repository's URI.
Show output
Filename: pool/main/c/cowsay/cowsay_3.03+dfsg2-8_all.deb
Size: 21372
SHA256: 5b16f90ff97871aa0f442087abc1878940d00e310f74190ba854a097545204bf
Ask about one specific version
apt-cache show cowsay=3.03+dfsg2-8 | head -3
The name=version form works anywhere apt takes a package name, including apt install. Without it you get the candidate, which may not be the version you are asking about.
Show output
Package: cowsay
Version: 3.03+dfsg2-8
Installed-Size: 92
Notice that show prints every version it knows
apt-cache show bash-completion | grep '^Version:'
A stanza is printed per version rather than per package, so piping apt-cache show into grep can return more lines than you expected on a machine with several repositories configured.
Show output
Version: 1:99.0-1
Version: 1:2.16.0-7
Read the raw record apt keeps
apt-cache showpkg hello-tips
The internal view: which index files list the package, what it depends on, and what depends on it. Denser than show and rarely what you want, but it is the only place that names the index file a version was read from.
Show output
Package: hello-tips
Versions:
1.0-1 (/var/lib/apt/lists/_srv_vendor_dists_stable_main_binary-all_Packages.lz4)
Description Language:
File: /var/lib/apt/lists/_srv_vendor_dists_stable_main_binary-all_Packages.lz4
MD5:
Reverse Depends:
Dependencies:
1.0-1 -
Provides:
1.0-1 -
Reverse Provides:
Test whether apt knows a package name at all
apt-cache show nosuchpackage; echo "exit $?"
Unlike policy, show treats an unknown name as an error and says so. That makes it the one to use when a script needs to tell a typo from a package it has nothing to say about.
Show output
E: No packages found
exit 100
Check a name from a script
apt-cache show cowsay >/dev/null 2>&1 && echo known || echo unknown
Exit status rather than parsed output, so a change to the record's fields cannot break it. See Exit codes and error handling.
Show output
known
Watch a virtual package print nothing
apt-cache show default-mta; echo "exit $?"
A virtual package has no record of its own, so show prints nothing and still succeeds. apt-cache showpkg lists the real packages providing the name, under Reverse Provides.
Show output
exit 0
Read about a package the machine has never had
dpkg -s cowsay-off 2>&1 | head -1; apt-cache show cowsay-off | head -1
dpkg answers from what is installed and apt-cache answers from the archive, so the package dpkg has never heard of is one apt-cache can describe in full.
Show output
dpkg-query: package 'cowsay-off' is not installed and no information is available
Package: cowsay-off
Understand why showsrc has nothing to say
apt-cache showsrc cowsay 2>&1 | head -1
showsrc reads source package records, which come from deb-src lines that a default Debian install does not have. Add one to /etc/apt/sources.list.d/debian.sources and run apt update before expecting an answer.
Show output
E: You must put some 'deb-src' URIs in your sources.list
Finding a package by name or description
apt-cache search takes a regular expression and matches it against both package names and their descriptions, which is why a short search term returns so much. Everything here reads the cache, so a package added to the archive since your last apt update will not appear.
Search for a package
apt-cache search cowsay
Name on the left, short description on the right. The pattern matched all three of these in the name, but it would have matched a package whose description mentioned cowsay too.
Show output
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow
Search names only, ignoring descriptions
apt-cache search --names-only '^cow' | sort
--names-only (short form -n) is what narrows a search that has come back as pages of results. Results arrive in cache order rather than alphabetically, so pipe through sort if the order matters.
Show output
cowbuilder - pbuilder running on cowdancer
cowdancer - Copy-on-write directory tree utility
cowpatty - Brute-force WPA dictionary attack
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
Narrow a search with several terms
apt-cache search talking cow
Every pattern given has to match, in any order and anywhere in the record. Adding a term is usually faster than writing a cleverer regex.
Show output
cowsay - configurable talking cow
cowsay-off - configurable talking cow (offensive cows)
xcowsay - Graphical configurable talking cow
Match a package name exactly
apt-cache search --names-only '^cowsay$'
The pattern is a regular expression, so ^ and $ anchor it to the whole name. Without the anchors this would also match cowsay-off and xcowsay.
Show output
cowsay - configurable talking cow
Read the full record for each result
apt-cache search --full cowsay-off | head -6
--full swaps the one-line summary for the same record apt-cache show prints. Useful for searching and inspecting in one pass, and long enough that it usually wants a pipe.
Show output
Package: cowsay-off
Source: cowsay
Version: 3.03+dfsg2-8
Installed-Size: 23
Maintainer: James McDonald <james@jamesmcdonald.com>
Architecture: all
List package names without descriptions
apt-cache pkgnames cowsay
pkgnames takes a prefix rather than a regular expression, and matches only the start of the name. Debian's shell completion for package names is built on it.
Show output
cowsay
cowsay-off
List every package with a given prefix
apt-cache pkgnames cowsay-
A trailing hyphen is a quick way to see what a source package split itself into, once you know the naming pattern a project uses.
Show output
cowsay-off
Check a package name exists before using it
apt-cache pkgnames cowsay | grep -qx cowsay && echo available || echo "no such package"
grep -qx insists on a whole-line match, so a prefix that also matches longer names cannot pass. Faster than apt-cache show for the same question, because pkgnames never reads the records.
Show output
available
Count what a search would return
apt-cache search --names-only cow | wc -l
Worth doing before piping a broad search anywhere. The count comes from your machine's cache, so it depends on which repositories are configured.
Show output
Your output will differ: the count depends on which repositories your machine has configured and when it last updated
22
Count every package name apt knows
apt-cache pkgnames | wc -l
The size of the archive as your machine sees it. Adding a repository, or enabling contrib and non-free, moves this number.
Show output
Your output will differ: the count moves with the archive and with which components are enabled
68194
Following dependencies
depends reads forwards, from a package to what it needs; rdepends reads backwards, from a package to what needs it. Both answer from the archive, so neither is limited to what is installed unless you ask for that.
See what a package depends on
apt-cache depends cowsay
Each relationship gets a line, with the kind named on the left. Suggests and Recommends appear here alongside Depends, so this is a longer list than what installing the package would actually pull in.
Show output
cowsay
Depends: libtext-charwidth-perl
Depends: <perl:any>
perl
Suggests: filters
Suggests: cowsay-off
Show only the dependencies that are required
apt-cache depends -i cowsay
-i (--important) drops everything that is not a hard requirement, which cuts a long dependency list down to the part that decides whether the package can be installed at all.
Show output
cowsay
Depends: libtext-charwidth-perl
Depends: <perl:any>
perl
Read a virtual dependency
apt-cache depends default-mta
Angle brackets mean a virtual package, a name real packages provide rather than one of their own. Asking about one directly gives the name straight back; where a real package depends on a virtual one, depends indents the providers beneath it, as the <perl:any> line above does with perl.
Show output
<default-mta>
Limit the answer to packages you have
apt-cache depends --installed cowsay
The same query filtered to packages present on the machine, which is a quick way to see what a dependency chain has already brought in.
Show output
cowsay
Depends: libtext-charwidth-perl
Notice that depends hides version constraints
apt-cache depends cowsay-off
Depends: cowsay here, where the record says cowsay (>= 3.03+dfsg2-3). apt-cache show keeps the ranges, and you need them to work out why apt is refusing to install a particular version.
Show output
cowsay-off
Depends: cowsay
Breaks: cowsay
Replaces: cowsay
Follow a dependency chain all the way down
apt-cache depends --recurse -i cowsay | head -12
--recurse repeats the query on everything it finds. Without -i it follows Suggests and Recommends too, which on a normal package reaches a large part of the archive.
Show output
cowsay
Depends: libtext-charwidth-perl
Depends: <perl:any>
perl
libtext-charwidth-perl
Depends: libc6
Depends: perl-base
Depends: <perlapi-5.40.0>
perl-base
perl
Depends: perl-base
Depends: perl-modules-5.40
List every package a dependency chain reaches
apt-cache depends --recurse -i cowsay | grep '^[a-z]' | sort
Package names are unindented in this output and relationships are indented, so grep '^[a-z]' reduces the chain to the set of packages it touches. This is the whole transitive closure, including what is already installed.
Show output
cowsay
gcc-14-base
libbz2-1.0
libc6
libcrypt1
libdb5.3t64
libgcc-s1
libgdbm-compat4t64
libgdbm6t64
libperl5.40
libtext-charwidth-perl
perl
perl-base
perl-modules-5.40
zlib1g
See how much bigger a recursion gets without -i
echo "important: $(apt-cache depends --recurse -i cowsay | grep -c '^[a-z]')"; echo "everything: $(apt-cache depends --recurse cowsay | grep -c '^[a-z]')"
Following Suggests and Recommends as well turns a chain of a dozen packages into a large fraction of the archive, because those relationships have no reason to converge. Always pass -i unless you specifically want the wider answer.
Show output
Your output will differ: both counts depend on which repositories your machine has configured, and the second is a large fraction of the archive
important: 15
everything: 16690
Spell out the relationships to follow
apt-cache depends --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances cowsay
What -i is shorthand for. The long form is worth knowing because each flag can be used on its own, so you can drop Suggests while keeping Recommends.
Show output
cowsay
Depends: libtext-charwidth-perl
Depends: <perl:any>
perl
Find out what depends on a package
apt-cache rdepends cowsay
What would be affected if this package went away. Packages appear once per relationship rather than once each, which is why cowsay-off is listed three times: it declares Depends, Breaks and Replaces on cowsay.
Show output
cowsay
Reverse Depends:
cowsay-off
presentty
junior-games-text
games-toys
cowsay-off
cowsay-off
ansible
ansible-core
Get a reverse dependency list without duplicates
apt-cache rdepends cowsay | tail -n +3 | sort -u
tail -n +3 drops the two header lines and sort -u collapses the repeats, leaving one line per package. Worth doing before counting anything.
Show output
ansible
ansible-core
cowsay-off
games-toys
junior-games-text
presentty
Show only packages that truly require it
apt-cache rdepends -i cowsay
The same filter as on depends, and it changes the answer considerably. Most of the list above is Suggests and Recommends, so only these two would actually break.
Show output
cowsay
Reverse Depends:
cowsay-off
presentty
Check whether anything installed needs a package
apt-cache rdepends --installed cowsay
An empty list under the header means nothing on this machine depends on the package, so removing it will not take anything else with it. Compare with apt remove --dry-run, which answers the same question from the other direction.
Show output
cowsay
Reverse Depends:
The cache itself
The cache is a binary index built from the files apt update downloads into /var/lib/apt/lists/. These commands describe it rather than any package in it, and the numbers they print will differ on every machine.
See how big the package cache is
apt-cache stats | head -3
Total package names counts every name apt has seen, real and virtual. It is far larger than the number of installable packages, which the next lines break down.
Show output
Your output will differ: every figure here depends on which repositories your machine has configured and when it last updated
Total package names: 159757 (5112 k)
Total package structures: 143561 (6317 k)
Normal packages: 67868
Tell real packages from virtual ones
apt-cache stats | grep -E 'Normal|virtual'
Normal are packages you can install. The other three count virtual names: Pure where no real package carries the name at all, as with default-mta, Single where exactly one package provides it, and Mixed where a real package of that name exists as well.
Show output
Your output will differ: the counts depend on which repositories your machine has configured
Normal packages: 67868
Pure virtual packages: 1097
Single virtual packages: 64623
Mixed virtual packages: 327
Rebuild the cache from the downloaded lists
apt-cache gencaches
Re-reads /var/lib/apt/lists/ and rewrites the binary index without fetching anything. The repair for a cache that has been corrupted, and the one apt-cache command that writes to disk.
Show output
Reading package lists...