Software ManagementLesson 1 of 4
Asking questions of the RPM database
Find which package owns a file, what a package contains, where its configuration lives and whether it has been altered.
rpmrpm -qrpm -qarpm -qirpm -qlrpm -qfrpm -qcrpm -qdrpm -Vrpm -qprpm -K
After this lesson you can
- Use the query options of rpm to find a package, its files, configuration files and documentation.
- Find the package that provides a file, and inspect an RPM file before installing it.
- Verify installed files against the database and read the result.
The idea
Every file installed from a package is recorded in the RPM database. That makes rpm a question-answering tool: which package put this here, what else did it install, what are its config files, did anyone change them? Learn the queries and you can understand an unfamiliar server quickly.
A package name looks like chrony-4.6.1-1.el10.x86_64: name, version, release (the distributor’s build number, .el10 is RHEL 10) and architecture.
All query commands are rpm -q plus a selector. Add a second letter for what to show.
| Command | Answers |
|---|---|
rpm -q NAME | Is it installed, which version? |
rpm -qa | Every installed package (pipe to grep, wc -l) |
rpm -qi NAME | Description, version, build date, vendor, signature |
rpm -ql NAME | Every file the package installed |
rpm -qc NAME | Only its configuration files |
rpm -qd NAME | Only documentation files (man pages, README) |
rpm -qf /path/file | Which installed package owns this file |
rpm -q --scripts NAME | Install and removal scripts |
rpm -q --requires NAME | What it depends on |
rpm -V NAME | Has any of its files changed since install? |
Add p to query a package file instead of the database: rpm -qip file.rpm, rpm -qlp file.rpm. This lets you look inside an RPM before you install it.
rpm -qf only knows about files that are installed. For “which package would give me this command” use dnf provides, which searches the repositories:
dnf provides /usr/sbin/semanage
dnf provides '*/semanage'
Try it
rpm -q bash chrony nonexistent
bash-5.2.26-6.el10.x86_64
chrony-4.6.1-1.el10.x86_64
package nonexistent is not installed
rpm -qf /etc/ssh/sshd_config
openssh-server-9.9p1-5.el10.x86_64
rpm -qc chrony
rpm -qd chrony | head -3
/etc/chrony.conf
/etc/chrony.keys
/etc/logrotate.d/chrony
/usr/share/doc/chrony/FAQ
/usr/share/doc/chrony/NEWS
/usr/share/doc/chrony/README
Run rpm -qc before you edit anything under /etc: it tells you exactly which files the package expects you to customise.
Look before you install
dnf download tree
rpm -qip tree-*.rpm | head -4
rpm -qlp tree-*.rpm
rpm -K tree-*.rpm
Name : tree
Version : 2.1.0
Release : 6.el10
Architecture: x86_64
/usr/bin/tree
/usr/share/doc/tree/LICENSE
/usr/share/doc/tree/README.md
/usr/share/man/man1/tree.1.gz
tree-2.1.0-6.el10.x86_64.rpm: digests signatures OK
rpm -K checks digests and the GPG signature. If it reports NOKEY, the signing key is not imported yet (rpm --import KEYFILE); the package is not necessarily bad, but it is unverified.
Verify installed files
rpm -V openssh-server
echo '# test' | sudo tee -a /etc/ssh/sshd_config
rpm -V openssh-server
# test
S.5....T. c /etc/ssh/sshd_config
The first command prints nothing because nothing differs (the # test line is tee echoing what it appended). The nine characters stand for: Size, Mode, 5 (digest), Device, Link, User, Group, Time, Pcapabilities. A dot means unchanged. The c marks a configuration file. A changed config file is normal, a changed binary (/usr/bin/...) deserves attention.
Going further
rpm -qa --last | head lists packages by install time, newest first: the quickest way to answer “what changed on this server recently”. rpm -q --qf '%{NAME} %{VERSION}\n' PACKAGE formats the output, and rpm -qa --qf '%{SIZE} %{NAME}\n' | sort -n | tail finds the largest packages. rpm -ivh and rpm -e install and erase directly, but they do not resolve dependencies; use dnf for those and keep rpm for questions.
Practice
0 of 5 done
Do these on your own system. They get harder. Check each result, then tick it off.
- Warm-up
Is it installed, and which version?
Check whether
bash,chronyandnonexistentare installed. List how many packages are installed in total.Check your result
rpm -q bash chrony nonexistentprints a name-version-release for the first two andpackage nonexistent is not installedfor the third.rpm -qa | wc -lprints a number.Hint
rpm -q NAME...can take several names.rpm -qalists everything.Solution
rpm -q bash chrony nonexistent rpm -qa | wc -l - Practice
Which package owns this file?
Find the package that owns
/etc/ssh/sshd_configand the package that owns/usr/bin/passwd. Then find which package would provide/usr/sbin/semanageeven though it is not installed.Check your result
rpm -qfnamesopenssh-serverandpasswd.dnf provides /usr/sbin/semanagenamespolicycoreutils-python-utils.Hint
rpm -qf PATHasks about installed files only.dnf providessearches the repositories, and*/semanagealso works.Solution
rpm -qf /etc/ssh/sshd_config rpm -qf /usr/bin/passwd dnf provides /usr/sbin/semanage - Practice
What does this package contain?
For
chrony, show its summary, version and install date. List its configuration files and its documentation files separately. Count how many files it installs.Check your result
rpm -qishows Name, Version, Install Date and Summary.rpm -qc chronyincludes/etc/chrony.conf.rpm -qd chronylists man pages.rpm -ql chrony | wc -lprints a number.Hint
-iinfo,-cconfig files,-ddocumentation,-lall files. Combine with-q NAME.Solution
rpm -qi chrony | grep -E '^(Name|Version|Install Date|Summary)' rpm -qc chrony rpm -qd chrony rpm -ql chrony | wc -l - Practice
Look inside an RPM file before installing it
Download the
treepackage without installing it (dnf download tree). Display its description, its file list and its scripts using the-pform of the query options, and check its signature.Check your result
rpm -qip tree.rpmprints the package info,rpm -qlplists/usr/bin/tree, andrpm -K tree.rpmreportsdigests signatures OK(orOKafter the Red Hat key is imported).Hint
Add
pto query a package file rather than the database.rpm -qp --scripts FILEshows install scripts.Solution
mkdir -p ~/lab/rpms && cd ~/lab/rpms dnf download tree rpm -qip tree*.rpm | head -12 rpm -qlp tree*.rpm rpm -qp --scripts tree*.rpm rpm -K tree*.rpm - Challenge
Has anything been changed?
Verify the
openssh-serverpackage. Add a harmless comment line to/etc/ssh/sshd_config, verify again, and explain every character of the line thatrpm -Vprints for the file. Restore the original file afterwards.Check your result
Before the edit
rpm -V openssh-serverprints nothing. After it prints a line such asS.5....T. c /etc/ssh/sshd_config:Ssize,5digest,Tmodification time differ, andcmarks a configuration file.Hint
Back up the file first with
cp -a. Each position in the nine-character string is one attribute; a dot means that attribute matches.Solution
sudo cp -a /etc/ssh/sshd_config /root/sshd_config.orig rpm -V openssh-server echo '# test comment' | sudo tee -a /etc/ssh/sshd_config rpm -V openssh-server sudo cp -a /root/sshd_config.orig /etc/ssh/sshd_config rpm -V openssh-server