Synopsis

inventory [-i | --include-base-packages] [-b | --bare | -C | --coverage | -j | --jsonl | -t | --tsv | -p | --probe] [-r | --reverse] [-v | --verbose]

Description

inventory reports installed packages known to supported package managers. It probes each supported installer, skips installers that are not available on the host, gathers package records, sorts them by date, and writes a report to standard output.

Each package record has these fields:

  • date

  • installer

  • package

  • version

  • summary

By default, the report is sorted newest first. Packages without a usable date sort as older than packages with dates.

Options

-i, --include-base-packages

Include packages considered part of the base system installation. By default, inventory omits base/system packages where the installer can identify them.

-b, --bare*

Write only the installer and package fields, separated by a tab, with no header row. This format is intended for tests and simple set comparisons.

-j, --jsonl

Write one JSON object per package record, one record per line.

--tsv

Write a tab-separated report with a header row.

-C, --coverage

List all package-manager backends supported by inventory, one display name per line, then exit without probing the host or collecting package records.

-p, --probe

List the supported package managers found on this system, one name per line, then exit without collecting package records.

-r, --reverse

Reverse the date sort order. The default order is newest first; this option sorts oldest first.

-v, --verbose

Report installer probing and collection diagnostics to standard error. This does not change the selected standard-output report format.

Output Formats

The default output format is a padded text report. The fields before the summary are right-padded to the width of the longest value in that field. The summary field is not padded.

The --tsv output format writes the same fields separated by tab characters. Tab, carriage-return, and newline characters inside field values are replaced with spaces. Version is omitted.

The --bare output format writes one tab-separated installer and package pair per line, with no header.

The --jsonl output format writes one JSON object per line. It is intended for programs that want to consume the inventory without parsing text columns.

The --probe output is not a package report. It writes one supported installer name per line in probe order.

The --coverage output is not a package report. It writes one supported package-manager backend display name per line in inventory’s backend order.

Supported Installers

apt (Debian-family Linux, including Ubuntu and variants)

Uses dpkg-query(1) to enumerate installed packages. Package summaries come from dpkg metadata. Package dates come from dpkg logs when possible, with a lower-confidence fallback to dpkg info-file mtimes.

pacman (Arch-family Linux)

Reads Arch Linux installed-package metadata from /var/lib/pacman/local. Names, versions, descriptions, and install dates come from pacman’s local package database.

dnf (Fedora-family and RHEL-family Linux)

Uses dnf repoquery --userinstalled by default to enumerate user-installed packages. With --include-base-packages, it uses dnf repoquery --installed instead.

tdnf (Photon OS and other Tiny DNF RPM systems)

Uses tdnf repoquery --userinstalled by default to enumerate user-installed packages. With --include-base-packages, it reports all installed RPM packages. Package details come from the RPM database.

urpmi (Mageia and Mandriva-family RPM Linux)

Reads RPM package records and, by default, omits packages listed in /var/lib/rpm/installed-through-deps.list, which urpmi uses to track packages selected indirectly as dependencies. With --include-base-packages, all installed RPM packages are reported.

rpm-ostree (Fedora Atomic, Fedora CoreOS, RHEL for Edge)

Uses rpm-ostree status --json to enumerate layered packages, requested local packages, and base package replacements from the booted deployment. Package details come from the RPM database. With --include-base-packages, it reports all installed RPM packages in the booted deployment.

yum (legacy RHEL-family Linux, Amazon Linux 2)

Uses yum history userinstalled by default on legacy yum systems, falling back to yumdb reason=user metadata when available. Package details come from the RPM database. With --include-base-packages, or when yum user-installed metadata is unavailable, it reports all installed RPM packages.

zypper (openSUSE and SUSE Linux Enterprise)

Uses zypper packages --user-installed by default to select user-installed packages, then reads names, versions, install times, and summaries from RPM package metadata. With --include-base-packages, it uses zypper packages --installed-only instead.

rpm (generic RPM-based Linux)

Uses rpm(8) as a fallback when no higher-level RPM package manager is available. Names, versions, install times, and summaries come from the RPM database. The default mode and --include-base-packages mode are identical.

apk (Alpine Linux)

Reads Alpine Linux installed-package metadata from /lib/apk/db/installed. Names, versions, and descriptions come from apk’s local package database.

eopkg (Solus Linux)

Reads Solus installed-package metadata from /var/lib/eopkg/package. By default, it omits packages listed in eopkg’s automatic-install marker. With --include-base-packages, all installed eopkg packages are reported.

swupd (Clear Linux OS)

Uses swupd bundle-list --status to enumerate installed bundles. By default, it reports explicitly installed bundles. With --include-base-packages, it reports both explicitly and implicitly installed bundles. The version field is the installed Clear Linux OS version reported by swupd info, when available.

pkgtools (Slackware Linux)

Reads Slackware installed-package records from /var/lib/pkgtools/packages, falling back to /var/log/packages. Names, versions, architectures, build numbers, and summaries come from pkgtools package records.

emerge (Gentoo Linux)

By default, selects packages from Portage’s selected package atoms in /var/lib/portage/world and static selected sets under /etc/portage/sets, then reads installed-package metadata from /var/db/pkg. With --include-base-packages, all installed Portage packages are reported. Package names include their Gentoo category, for example app-editors/vim.

xbps (Void Linux)

Uses xbps-query -m by default to select manual packages on Void Linux, minus the transitive installed dependency closure of base-system. With --include-base-packages, it uses xbps-query -l to enumerate all installed packages. Names, versions, and descriptions come from XBPS package metadata; install dates are queried from XBPS package properties when available.

flatpak (most Linux distributions)

Uses flatpak list --app by default to enumerate installed applications. With --include-base-packages, it uses flatpak list to include runtimes and other refs. Package dates are inferred from the mtime of the Flatpak deployment location reported by flatpak info.

snap (Ubuntu and other Linux distributions)

Uses snap list to enumerate installed snaps. By default, it omits snaps that snap info or snap list identify as base, core, snapd, kernel, or gadget snaps, and omits common runtime/content support snaps by name. With --include-base-packages, all listed snaps are reported. Package dates are inferred from the mtime of the installed snap revision file when available. Summaries are read from snap info.

pip (most Linux and BSD systems)

Uses pip list --json to enumerate applications installed in pipx-managed virtual environments. Names and versions come from pip metadata.

pipx (most Linux and BSD systems)

Uses pipx list --json to enumerate applications installed in pipx-managed virtual environments. Names and versions come from pipx metadata.

cargo (most Linux and BSD systems)

Uses cargo install --list to enumerate Rust crates installed as command-line tools. Versions come from cargo’s installed-crate listing.

go (most Linux and BSD systems, macOS)

Scans GOBIN and GOPATH/bin for executable Go command binaries, then uses go version -m to read embedded build information. Package names come from the main package path when available. Versions come from the main module version embedded in the binary. The Go module cache is not reported as installed inventory; cached modules under GOMODCACHE are build inputs, not installed command packages.

gem (most Linux and BSD systems)

Uses RubyGems metadata to enumerate locally installed gems. Names, versions, and summaries come from RubyGems specifications.

cpan (most Linux and BSD systems)

Uses Perl’s ExtUtils::Installed metadata to enumerate locally visible CPAN-style Perl module installations. Names and versions come from Perl packlist metadata when available. Dates prefer perllocal.pod entries and fall back to .packlist or installed-file mtimes. Summaries are best-effort extracts from module POD NAME sections.

nix (NixOS, Linux, macOS)

Uses nix profile list --json and nix-env --query --installed --json --meta when those commands are available. Names and versions come from Nix profile or nix-env metadata; descriptions are available from legacy nix-env metadata when Nix reports them.

guix (Guix System and other GNU/Linux distributions)

Uses guix package --list-installed to enumerate packages installed in the current Guix profile. Names, versions, output names, and store paths come from Guix profile metadata.

npm (most Linux and BSD systems)

Uses npm root -g and scans the global package tree when that tree is owned by root and is outside the invoking user’s home directory. This is intended to capture npm packages installed systemwide in root mode, not packages installed under a user-local npm prefix. Package names, versions, and descriptions are read from each package’s package.json file.

yarn (most Linux and BSD systems)

Uses yarn global dir and scans the global Yarn package tree. Package names, versions, and descriptions are read from each package’s package.json file.

macports (macOS)

Uses port -q installed requested by default to enumerate ports explicitly requested by the user. With --include-base-packages, it uses port -q installed active to enumerate all active installed ports. Names, versions, variants, and active state come from port installed. Summaries come from port info --description --index. Dates prefer the MacPorts registry when available, falling back to MacPorts software-image mtimes.

homebrew (macOS and Linux)

Uses brew list --formula --json=v2 and brew list --cask --json=v2 to enumerate installed Homebrew formulae and casks. Formula names, versions, and descriptions are read from Homebrew’s JSON metadata. Cask tokens, versions, and descriptions are read from Homebrew’s cask JSON metadata.

pkgsrc (NetBSD, SmartOS/illumos, Linux, macOS, and other pkgsrc systems)

Uses pkg_info -X -u by default to enumerate user-installed pkgsrc packages in pkg_summary(5) format. With --include-base-packages, it uses pkg_info -X -a to include automatic dependency packages. Names, versions, and comments come from pkgsrc package metadata.

pkg (FreeBSD)

Uses FreeBSD pkg query -e "%a = 0" by default to enumerate non-automatic packages. With --include-base-packages, it uses pkg query -a to enumerate all installed packages. Names, versions, install times, and comments come from the FreeBSD package database.

Date Stamps

Date stamps are best-effort package hints, not authoritative audit records. Package managers do not expose a uniform installed-or-last-updated timestamp, and some do not persist one at all. Non-empty dates are normalized to UTC and emitted as RFC 3339-style timestamps ending in Z, for example 2026-05-17T14:30:00Z.

For apt, the preferred source is retained files matching /var/log/dpkg.log*. These logs record install and upgrade events, but they are commonly rotated and eventually deleted. If no matching log entry remains, inventory falls back to the mtime of /var/lib/dpkg/info/PACKAGE.list. This fallback can fill otherwise empty dates, but it is less reliable: file mtimes can be affected by backups, restores, filesystem copies, dpkg behavior, and package transitions.

For flatpak, dates are inferred from deployment-directory mtimes. These may change when Flatpak rewrites deployment metadata or when filesystem operations touch the deployment tree.

For snap, dates are inferred from installed revision-file mtimes. These are usually close to install or refresh time, but can also reflect local file restoration or snapd storage behavior.

For pacman, dates come from the INSTALLDATE field in pacman’s local package database, falling back to the mtime of the package’s local desc file. These values can be affected by database restoration, filesystem copying, or manual metadata changes.

For rpm-ostree, dnf, tdnf, urpmi, yum, zypper, and rpm, dates come from the RPM database’s INSTALLTIME field. This is usually the install or upgrade time recorded by RPM, but it can be affected by RPM database rebuilds, system-image construction, backup restores, or package database migration.

For pip and pipx, dates are inferred from venv metadata or venv directory mtimes. These may reflect virtual-environment repair, package upgrades, backup restoration, or other filesystem operations rather than the original install time.

For apk, Alpine’s installed-package database does not provide a uniform per-package install timestamp. inventory therefore uses the mtime of the local installed-package database as a low-confidence fallback, which may be identical for many packages and may simply indicate the most recent apk database write.

For eopkg, dates are inferred from installed package metadata-file mtimes. These may reflect package installation or upgrade, but can also reflect package database rebuilds, backup restoration, filesystem copying, or metadata repair.

For swupd, per-bundle install timestamps are not exposed through the bundle list interface, so the date field is left empty.

For pkgtools, dates are inferred from installed-package record mtimes. These may reflect package installation or upgrade, but can also reflect package database migration, backup restoration, filesystem copying, or metadata touching.

For emerge, dates prefer Portage’s BUILD_TIME metadata, falling back to VDB file or directory mtimes. Build time is often close to install time for source builds, but it is not guaranteed to be the exact package installation time.

For xbps, dates come from the XBPS install-date property when available. If XBPS cannot report that property, the date field is left empty.

For cargo, dates are inferred from the mtimes of installed binaries under CARGO_HOME/bin, falling back to cargo’s installed-crates metadata file. These may reflect rebuilds, reinstalls, or file restoration.

For go, dates are inferred from the mtimes of command binaries under GOBIN and GOPATH/bin. These may reflect rebuilds, reinstalls, cross-compiled installs, backup restoration, or filesystem copying rather than the original go install time.

For gem, dates are inferred from RubyGems specification-file mtimes. These may reflect packaging defaults, distribution integration, Ruby upgrades, backup restores, or filesystem copies rather than original gem install time.

For cpan, dates prefer perllocal.pod installation records when present, falling back to .packlist mtimes and then installed-file mtimes. These records are best-effort only: pure_install can bypass perllocal.pod, packlist files may be missing or regenerated, and file mtimes may reflect archive timestamps, filesystem copying, or backup restoration rather than the original CPAN client operation.

For yarn, dates are inferred from package.json mtimes in the global package tree. As with npm, these may reflect extraction time, archive timestamps, rebuilds, or later file-touching operations.

For FreeBSD pkg, dates come from the package database’s install-time field. These values can be affected by database migration, image construction, backup restores, or package database repair.

For pkgsrc, dates are inferred from pkgsrc package-database entry mtimes under PKG_DBDIR when that directory can be discovered through pkg_admin or common defaults. These values can be affected by database migration, backup restores, filesystem copying, or package database repair.

For guix and nix, dates are inferred from installed store-path mtimes when store paths are available. These are low-confidence inventory hints: store paths may be copied, substituted from caches, shared by multiple profiles, retained after profile changes, or have mtimes unrelated to the profile operation that made the package visible.

For npm, dates are inferred from package.json mtimes in the global package tree. These may reflect extraction time, package archive timestamps, rebuilds, or later file-touching operations rather than the exact npm install time.

For macports, dates prefer the timestamp recorded in the MacPorts registry when available. If no registry date can be read, dates are inferred from MacPorts software-image mtimes under the active prefix. These values may be affected by registry migration, image archive rebuilding, cleanup operations, backup restoration, filesystem copying, or local metadata repair.

For homebrew, formula dates prefer the timestamp recorded in INSTALL_RECEIPT.json under the package’s Cellar version directory, falling back to receipt-file or version-directory mtimes. Cask dates are inferred from the mtime of the package’s Caskroom directories. These values can be affected by Homebrew cleanup, migration between prefixes, backup restoration, filesystem copying, and local metadata rewrites.

An empty date means inventory could not find a usable timestamp. When sorting, empty or unparseable dates are treated as oldest.

Base-System Filtering

By default, inventory asks each backend for user-installed or otherwise non-base packages. With --include-base-packages, backends fetch all installed packages instead.

The dnf, tdnf, zypper, macports, pkgsrc, eopkg, swupd, and pkg package tools have reliable metadata for distinguishing user-installed packages from dependency-installed packages.

For package managers that do not expose user-installed or base-system information, the two modes will be identical. This includes apk, pip, pipx, rpm, pkgtools, cargo, go, npm, yarn, gem, guix, nix (when not running directly over NixOS), and homebrew (when not running as the OS base manager).

For other package managers, this filter is best-effort. It may omit packages that the user considers interesting, or include packages that were effectively part of the initial system image.

For apt-based systems, inventory first looks for Debian/Ubuntu installer manifests such as /var/log/installer/initial-status. If no installer manifest is available, it falls back to a heuristic based on apt-mark showmanual, dpkg package priority, and dpkg essential-package metadata.

For pacman-based systems, if an installed base metapackage exists, inventory omits base and the transitive closure of its installed dependencies. Versioned dependencies are matched by package name, and virtual dependencies are matched through installed package PROVIDES metadata.

For rpm-ostree systems, inventory reports layered packages and base package replacements from the booted deployment by default. With --include-base-packages, it reports the full RPM database for that deployment.

For yum-based systems, inventory uses yum history userinstalled or yumdb reason=user metadata when available. If neither source is available, the yum default and --include-base-packages modes are identical.

For urpmi systems, inventory omits packages listed in /var/lib/rpm/installed-through-deps.list, which urpmi uses for orphan detection. This distinguishes explicitly requested packages from dependency packages, but does not identify the original base install.

When inventory falls back to raw rpm database queries, no user-installed or base-system metadata is available, so default and --include-base-packages modes are identical.

For Flatpak, inventory uses flatpak list --app by default, excluding runtimes and extensions. For Snap, there is no exact CLI query for manually requested snaps; inventory therefore filters base/core/snapd/kernel/gadget snaps when reported by snapd metadata or list notes, and filters common runtime/content support snaps by name.

For Gentoo Portage, inventory treats packages selected in /var/lib/portage/world as user-selected and expands static selected package sets listed in /var/lib/portage/world_sets when the set definition exists under /etc/portage/sets. Dynamic Portage sets are not expanded. Atom matching uses portageq match when available, with a direct category/package fallback.

For XBPS, inventory uses xbps-query -m to select manual packages, then omits base-system and the transitive closure of its installed dependencies as reported by xbps-query -x. This is a manual-vs-automatic package-manager state filtered against Void’s base metapackage, not provenance.

For CPAN-style Perl installs, inventory cannot distinguish explicitly requested modules from modules installed as dependencies. By default it omits the Perl runtime record and records whose packlists appear to live under Perl core or vendor library directories, because those are usually base Perl or operating-system package-manager contents. With --include-base-packages, those records are included when Perl reports them.

For pkgsrc, inventory uses pkg_info -u by default to select packages not marked automatic by pkgsrc. pkgsrc normally manages third-party packages rather than the operating-system base.

For MacPorts, inventory uses the requested pseudo-port selector by default. MacPorts normally sets this flag for ports named explicitly on port install and leaves dependency-installed ports unrequested. With --include-base-packages, inventory reports all active ports, including unrequested dependencies. Inactive installed images are not reported, because they are not the active package state in the MacPorts prefix.

Exit Status

0

Successful completion.

Nonzero

Command-line parsing failed or Python terminated with an unhandled exception.

Installer-specific failures are reported to standard error when possible, and collection continues with the remaining installers.

If no supported package manager is available, inventory writes a warning to standard error and emits an empty report in the requested output format. With --probe, the same warning is written and no package-manager names are emitted.

Files

/var/log/dpkg.log*

APT/dpkg install and upgrade logs used for preferred apt date stamps.

/var/lib/dpkg/info/.list*

APT fallback source for package dates.

/var/log/installer/initial-status

Debian/Ubuntu installer manifest used for base-system filtering when present.

/var/lib/pacman/local

Arch Linux pacman local package database.

RPM database

RPM package database queried for rpm-ostree, dnf, tdnf, urpmi, yum, zypper, and rpm package records.

rpm-ostree status --json

Booted deployment metadata used for rpm-ostree base-system filtering.

/var/lib/rpm/installed-through-deps.list

urpmi dependency-installed package marker used for default urpmi filtering.

/var/lib/yum/yumdb

Legacy yum database used for yum base-system filtering when present.

pipx home

pipx virtual-environment tree used for pipx package dates.

/lib/apk/db/installed

Alpine Linux apk installed-package database.

/var/lib/eopkg/package

Solus eopkg installed-package metadata tree.

/var/lib/eopkg/info/auto_installed

Solus eopkg automatic-install marker used for default eopkg filtering.

swupd bundle-list --status

Clear Linux bundle status used for default swupd filtering.

/var/lib/pkgtools/packages

Slackware pkgtools installed-package database.

/var/log/packages

Legacy Slackware installed-package database path.

/var/db/pkg

Gentoo Portage installed-package database.

/var/lib/portage/world

Gentoo Portage selected-package atoms used for default emerge filtering.

/var/lib/portage/world_sets

Gentoo Portage selected package sets used for default emerge filtering.

/etc/portage/sets

Static Gentoo package-set definitions expanded for default emerge filtering.

XBPS package database

Void Linux XBPS package database queried through xbps-query.

CARGO_HOME

Cargo installation tree used for cargo-installed Rust tools.

GOBIN

Go command installation directory scanned when set.

GOPATH/bin

Default Go command installation directory scanned for each GOPATH entry.

RubyGems specification files

RubyGems metadata files used for gem package dates.

Perl perllocal.pod and .packlist files

Perl module installation metadata used for CPAN package names, versions, and dates when reported by ExtUtils::Installed.

MacPorts registry

MacPorts installed-port registry used for MacPorts package dates when readable.

MacPorts software-image tree

MacPorts image archive tree under the active prefix, used as a fallback for MacPorts package dates.

Yarn global package tree

Global Yarn package tree reported by yarn global dir.

FreeBSD pkg database

FreeBSD package database queried through pkg query.

pkgsrc package database

pkgsrc package database under PKG_DBDIR, commonly /usr/pkg/pkgdb or /var/db/pkg, queried through pkg_info and pkg_admin.

/nix/store

Nix store paths used for Nix package date stamps when reported by Nix metadata.

/gnu/store

Guix store paths used for Guix package date stamps.

$(brew --prefix)/Cellar

Homebrew formula tree used for formula date stamps.

$(brew --prefix)/Caskroom

Homebrew cask tree used for cask date stamps.

See Also

apt(8), dpkg-query(1), flatpak(1), snap(8), pacman(8), dnf(8), rpm-ostree(1), tdnf(8), urpmi(8), urpmi.files(5), yum(8), zypper(8), rpm(8), pipx(1), apk(8), eopkg(1), swupd(1), pkgtool(8), installpkg(8), emerge(1), xbps-query(1), cargo-install(1), go(1), gem(1), cpan(1), yarn(1), port(1), port-installed(1), pkg(8), pkg_info(1), pkg_admin(1), pkgsrc(7), guix(1), nix(1), nix-env(1), npm(1), brew(1)

Author

Eric S. Raymond <esr@thyrsus.com>