If you have ever needed to figure out which package on a Linux or BSD box owns a specific file, you already know the dance. Fedora has dnf provides, Debian has apt-file, FreeBSD has pkg provides. The question of what to do on NetBSD, where the package manager is pkgin and the underlying ports tree is pkgsrc (the NetBSD Packages Collection, a framework for building third-party software from source), comes up often enough that the answer deserves to be written down clearly.
The short version: pkgsrc ships a tool called pkgfile (and a related one called pkglocate) that does exactly this lookup, but it is not in the base system and it is not indexed by default. You install it, you build its database, and you can ask “which package would have shipped bin/mplayer” in about a second.
The pkgfile approach
The pkgfile package is a pkgsrc addition maintained as part of the wider pkgsrc infrastructure. It walks the pkgsrc tree (the directory hierarchy that contains every package recipe) and indexes which files each package installs. After the index is built, you can query it with a glob (a wildcard pattern that matches partial file paths) the same way you would on Fedora or Debian.
The basic flow on a NetBSD system with pkgsrc installed is:
- Install pkgfile from pkgsrc (
pkgin install pkgfileor build it frompkgsrc/sysutils/pkgfile) - Run
pkgfile -uonce to build the local database of file-to-package mappings - Query with
pkgfile bin/mplayerto get the package that would provide that file
The -u step is the one people forget. Without an up-to-date database, the tool tells you nothing. The database is local to the machine, so if you install a new package you have not seen before, run -u again or expect the new package not to appear in your results. This is the same gotcha as apt-file update on Debian and the equivalent pkg provides -u on FreeBSD.
What if you are not on NetBSD
The pkgfile tool is pkgsrc-specific. If you are running pkgsrc on a Linux distribution (which is a supported configuration, called “pkgsrc on Linux” or just “Linux pkgsrc”), the same pkgfile command works the same way. The pkgsrc build system is portable across NetBSD, FreeBSD, OpenBSD, macOS, and several Linux distributions including Debian, Fedora, and Alpine. The pkgfile database is built from the pkgsrc tree, so the file-to-package mappings are consistent regardless of which host OS you are on.
There is also a separate question worth raising, because the original poster was specifically asking about NetBSD but the same problem exists on every Unix-like distribution with a package manager. Each distribution has its own tool, but the shape of the workflow is the same: a one-time index build, a query command that takes a file path or glob, and an output that names the package that would install that file. If you bounce between distributions (or you administer more than one), the muscle memory carries over once you have used two or three of them.
If you are not on pkgsrc at all and you only need a quick lookup, the per-distro commands still work:
- Fedora / RHEL / CentOS Stream:
dnf provides '*/bin/mplayer' - Debian / Ubuntu:
apt-file update && apt-file search mplayer | grep bin - FreeBSD:
pkg install -y pkg-provides && pkg provides -u && pkg provides '*/bin/mplayer$' - Void Linux:
xbps-query -Ro /bin/mplayer - Arch Linux:
pacman -F /bin/mplayer(requirespacman-contrib) - Alpine Linux:
apk search --no-cachedoes not support reverse file lookup natively, so the practical answer is to check the package contents via the Alpine package search at pkgs.alpinelinux.org - macOS (with Homebrew, the community-maintained package manager for macOS):
brew searchdoes not support reverse file lookup; the practical answer is to look up the formula on formulae.brew.sh and read its file list
The original Stack Exchange question listed three of these, and the answer is the NetBSD equivalent fits into the same shape: a separate index step, a query command, and a wildcard pattern. The interface is consistent because the underlying problem is the same.
The pkglocate alternative
pkglocate is a sibling tool in the pkgsrc tree that does a similar job but indexes the contents database of installed binary packages. Where pkgfile walks the pkgsrc tree to map files to package recipes, pkglocate is more useful when you have a populated /var/db/pkg (the directory where NetBSD and pkgsrc keep the installed-package database) and you want to know which installed package owns a file.
The two tools overlap in coverage but answer different questions:
pkgfileis the right call when the package is not installed and you want to know which package would install a given file pathpkglocateis the right call when the package may already be installed and you want to know which installed package on this system owns a given file
For a not-yet-installed scenario, the original use case in the Stack Exchange question, pkgfile is the answer. pkglocate is more useful for system administration tasks like “what package installed this mystery binary that I just found in /usr/pkg/bin.”
Trade-offs and footguns
The pkgfile database is local, which is the main design choice you have to live with. The -u step is the database build, and it walks the entire pkgsrc tree, so it is slow the first time you run it (a full pkgsrc checkout can be hundreds of thousands of files). Once it is built, queries are fast. The tool also has to be re-run whenever the underlying pkgsrc tree changes, which on a fresh checkout is “every time you sync the tree.”
Other things to know:
- The glob pattern matters.
pkgfile bin/mplayerwill not match/usr/pkg/bin/mplayerbecause the path anchor is the package-relative install path, not the absolute filesystem path - Wildcards need to be quoted in the shell so they are not expanded by your own shell before the tool sees them
- The pkgfile package itself is not part of the NetBSD base system, so on a fresh install you have to add it from pkgsrc before any of this works
- The database is per-machine, so a chroot or a sandbox has its own database; if you query from inside a chroot, you get chroot-local results
- The pkgfile database is also separate from any local pkgsrc binary package cache, so an installed package that was built locally from source rather than from a binary package may or may not appear, depending on which path pkgfile indexed
- If you keep your pkgsrc tree in a non-default location (some installations mount pkgsrc under /opt/pkgsrc or similar), you have to tell pkgfile where to look via the PKGSRCDIR environment variable, or the index build will silently walk the wrong tree
Bottom line
For NetBSD and pkgsrc, the answer to “which package would provide this file” is pkgfile, installed from pkgsrc, indexed once with -u, and queried with the relative path pattern. The interface is the same as dnf provides, apt-file search, and pkg provides. The unique wrinkle is that the database is local and you have to remember to refresh it. Once you do, the rest of the workflow is identical to every other Unix package manager that ships this kind of reverse lookup. The reason this is worth knowing on NetBSD specifically is that the base system is small and the pkgsrc tree is where the third-party software lives, so any binary you find in /usr/pkg/bin (the default pkgsrc install prefix, where most pkgsrc-installed binaries land) on a NetBSD box is overwhelmingly likely to have come from a pkgsrc package. Tracing it back to the package name is a one-command operation once pkgfile is set up. Without pkgfile, you are reading the pkgsrc tree by hand, which is technically possible but nobody wants to do that.