pkg-search(1)
NAME
pkg-search - search the repository chain by name, capability or file
SYNOPSIS
pkg search [options] query
pkg find [options] query
DESCRIPTION
You know roughly what you want, but not what it's called. Or you know the library some binary is screaming about, and you want to know who ships it. Or there's a file on disk and you'd like to know which package put it there. That's all one command.
By default the query is matched against package names. Each flag adds another thing to match against, and the results are added together. So pkg search ssl --provides finds everything with "ssl" in its name and everything that provides a capability with "ssl" in it.
How does a name match?
As a substring, ignoring case, against both the package name and the subpackage name. pkg search compress finds anything with "compress" anywhere in it.
How does a capability match?
The same way, against the namespace:name form of each capability. That's soname:libc.so.6 for a shared library, pkgconfig:glib-2.0 for a pkg-config module. You don't have to type the whole thing, but the more you type, the less noise you get.
Where does it look?
At the repository chain: everything the configured repositories make current. Building that index means parsing every current manifest in the chain, and that takes seconds. It's effectively the whole cost of the command.
If your question is about this machine, ask it with --installed. Then the chain is never touched, and the answer comes straight out of the installed set. That's a lot cheaper.
--file is the odd one out. Without --installed it searches the chain and the installed set, and every hit says which one it came from. If the installed state can't be read (the normal case when you're not root), you get a warning and still get the repository half of the answer. Under --installed there's no second half to fall back on, so an unreadable state is an error instead of a quiet "(no matches)".
FILE MATCHING
The rules are the same whether you're searching the chain or, under --installed, this machine. Matching is case-sensitive, because a path is an exact identifier, not prose. The slash decides what gets compared:
- A query with a
/in it matches the whole path:/usr/bin/gzip. - A query without one matches the file name alone. gzip finds
/usr/bin/gzip, but not/usr/bin/gzip.1or/usr/share/doc/gzip/README.
Two glob characters work on whichever of those the slash picked:
*- Any run of characters, including
/. ?- Exactly one character.
So '*.so.6' asks for a file name at any depth, and '/usr/lib64/*' asks for everything under a directory. Quote your globs, or the shell eats them first.
OPTIONS
--provides- Also match packages whose provides capabilities contain the query.
--requires- Also match packages whose requires capabilities contain the query.
--conflicts- Also match packages whose conflicts capabilities contain the query.
--file- Also match packages that ship a file the query names. See FILE MATCHING.
--installed- Answer from the installed set alone, and never build the chain index. Works with every other flag; with
--fileit answers which installed package ships a path.
All global options apply; see pkg(1).
OUTPUT
File hits come first, in their own table. They're never collapsed, since a path lives in exactly one subpackage. Installed hits are listed before the chain's:
source package version path installed gzip/bin 1.13-4 /usr/bin/gzip Common gzip/bin 1.13-4 /usr/bin/gzip
Name and capability hits follow, collapsed to one row per package with the runtime subpackage classes in brackets:
alsa-lib 1.2.16.1 [/bin, /lib] alsa-lib/dev 1.2.16.1
A capability hit tacks on what matched, past the bracket. What matched is part of what decides whether two subpackages may share a row, so two subpackages that matched for different reasons never fold together:
openssl 3.5.7 [/lib] (provides soname:libssl.so.3)
--collapse=none gives you one row per subpackage instead. The two levels that only make sense for an installed listing, sets and roots, are refused here; see pkg(1) and pkg-list(1).
And when there's nothing:
(no matches)
JSON
{ "ok": true, "query": "gzip", "hits": [ { "name":..., "subpkg":..., "version":..., "matched": [ { "rel": "provides", "capability": "..." } ] } ], "file_hits": [ { "source":..., "name":..., "subpkg":..., "version":..., "release":..., "path":... } ] }
source is installed, or the name of the repository that answers for the package.
EXAMPLES
By name
pkg search vim pkg search compress
Who provides a shared library?
pkg search --provides soname:libc.so.6 pkg search --provides soname:libssl.so.3
Who provides a pkg-config module?
pkg search --provides pkgconfig:glib-2.0
Who needs a shared library?
Worth asking before you remove something:
pkg search --requires soname:libfoo.so.1
What conflicts with a capability?
pkg search --conflicts file:/usr/bin/awk
Which package owns this path?
pkg search --file /usr/bin/gzip
Which package ships a file, wherever it lives?
pkg search --file gzip
Every shared library at version 6
pkg search --file '*.so.6'
Everything under a directory
pkg search --file '/usr/lib64/pkgconfig/' pkg search --file '/etc/'
A single-character wildcard
pkg search --file 'gz?p'
Several subjects at once
Name, provides and file, in one query:
pkg search ssl --provides --file
Scripting
pkg --json search --provides soname:libz.so.1 \ | jq -r '.hits[] | "(.name)/(.subpkg)"'
Is a path owned by anything at all?
pkg --json search --file /usr/bin/gzip | jq '.file_hits | length'
Only the installed half:
pkg --json search --file /usr/bin/gzip \ | jq '.file_hits[] | select(.source == "installed")'
Asking only about this machine
pkg search --installed vim pkg search --installed --file /usr/bin/gzip pkg search --installed --provides soname:libc.so.6
This beats the jq filter above. The chain index is never built at all, instead of built and then thrown away.
Searching a repository that isn't configured
pkg --repo /srv/mirror/Common --repos-dir /nonexistent search vim
Why is this search slow?
pkg -v search --file '*.so'
The -v lines show the index build, which is the expensive part on a large chain. If the answer is only about this machine, --installed skips that phase entirely.
EXIT STATUS
0 whether or not anything matched. Finding nothing isn't an error. 1 when the search couldn't be run: the chain couldn't be built, or, under --installed, the installed state couldn't be read.
SEE ALSO
pkg(1), pkg-list(1), pkg-info(1), pkg-query(1), pkg-install(1), pkg-chain(7), pkg-subpkgs(7)
docs/design/dependency-kinds.md