Skip to content

102.5 Use RPM and YUM package management

Weight: 3

Candidates should be able to perform package management using RPM, YUM and Zypper.

Objectives

  • Install, re-install, upgrade and remove packages using RPM, YUM and Zypper
  • Obtain information on RPM packages such as version, status, dependencies, integrity and signatures
  • Determine what files a package provides, as well as find which package a specific file comes from
  • Awareness of dnf

Terms

rpm, rpm2cpio, /etc/yum.conf, /etc/yum.repos.d/, yum, zypper

Introduction

The RPM Package Manager (rpm, also called RedHat Package Manager (RPM)) was developed by Red Hat. Today it is used by Red Hat Enterprise Linux (RHEL) and its relatives like Fedora, CentOS and Oracle Linux, by other distributions like openSUSE, and even by other systems like IBM's AIX. Packages are .rpm files.

On top of rpm sit the high-level tools that work with repositories and resolve dependencies:

Tool Used on
yum (YellowDog Updater Modified (YUM)) RHEL, CentOS, Oracle Linux, older Fedora
dnf (Dandified YUM) Fedora, a fork of yum
zypper SUSE Linux and openSUSE
Package management layers (same idea as Debian, different tools):

  Debian side                 Red Hat / SUSE side
  -----------                 -------------------
  apt-get / apt-cache         yum / dnf / zypper     high level: repositories, dependencies
        |                           |
        v                           v
  dpkg                        rpm                    low level: single packages
        |                           |
        v                           v
  .deb files                  .rpm files

The package format is the same, but distributions differ inside, so a package made for openSUSE may not work on RHEL, and the other way around. Always look for a package made for your distribution.

rpm: install, upgrade, freshen

The format is rpm ACTION [OPTION] package. The main actions:

Short Long What it does
-i --install install a package
-U --upgrade upgrade a package, or install it if it is not there yet
-F --freshen upgrade only if an older version is already installed
-e --erase remove a package
-q --query ask about packages
-V --verify check that an installed package's files are unchanged
-K --checksig check the integrity and signature of an .rpm file

Add -v for verbose output and -h to print hash signs (#, 50 of them) as a progress bar. Options can be combined, so rpm -i -v -h is rpm -ivh:

# rpm -ivh tmux-3.2a-4.fc36.x86_64.rpm
# rpm -Uvh tmux-3.3a-1.fc37.x86_64.rpm          # most of the time, use -U
# rpm -Uvh package.rpm                          # -v verbose, -h shows hash progress bar (50 # signs)
# rpm -Fvh *.rpm                                # only upgrade what is already installed

In practice we usually use -U, because it works for both a fresh install and an upgrade.

rpm actions at a glance:

  -i    install (fresh only)
  -U    install OR upgrade (use this most of the time)
  -F    upgrade only if already present
  -e    erase/remove
  -q    query (is it installed?)
  -V    verify (is it intact?)
  -K    checksig (is the .rpm file valid?)

rpm and dependencies

Like dpkg, rpm checks dependencies but cannot solve them. It lists what is missing and stops:

# rpm -i gimp-2.8.22-1.el7.x86_64.rpm
error: Failed dependencies:
    babl(x86-64) >= 0.1.10 is needed by gimp-2:2.8.22-1.el7.x86_64
    gegl(x86-64) >= 0.2.0 is needed by gimp-2:2.8.22-1.el7.x86_64
    gimp-libs(x86-64) = 2:2.8.22-1.el7 is needed by gimp-2:2.8.22-1.el7.x86_64
    libgimpui-2.0.so.0()(64bit) is needed by gimp-2:2.8.22-1.el7.x86_64
    ...

It is up to you to find the .rpm files for the dependencies (yum whatprovides, below, tells you which package has a missing file). If you have the package and all its dependencies in one directory, install them together and rpm will not complain about dependencies that are in the other files:

# rpm -Uvh *.rpm

If you really know what you are doing, --nodeps skips the dependency check and --force installs or upgrades despite all problems.

rpm keeps no record of automatically installed dependencies, so unlike yum it cannot remove them later.

rpm: removing packages

rpm -e removes a package without asking for confirmation. It refuses if another installed package needs it:

# rpm -e wget
# rpm -e tmux
error: Failed dependencies:
    tmux is needed by (installed) anaconda-install-env-deps-36.16.5-1.fc36.x86_64
# rpm -e unzip
error: Failed dependencies:
    /usr/bin/unzip is needed by (installed) file-roller-3.28.1-2.el7.x86_64

First remove the packages that depend on it (here file-roller). You can give several names to rpm -e to remove them at once.

rpm: querying packages

-q alone tells you whether a package is installed:

# rpm -q breezy
breezy-3.2.1-3.fc36.x86_64
# rpm -q emacs
package emacs is not installed

Combine -q with other letters:

Option Long Shows
-qa --all all installed packages
-qi --info information: version, release, install date, size, license, signature, description
-ql --list the files the package installed
-qc --configfiles only the configuration files
-qR (-R) --requires the dependencies
-qf --file which installed package owns a file
-q --whatprovides which package provides a capability or file
-p query a package file that is not installed, instead of the installed database

Easy to remember: -qa is "query all", -qi "query info", -ql "query list", -qf "query file".

# rpm -qa
selinux-policy-3.13.1-229.el7.noarch
pciutils-libs-3.5.1-3.el7.x86_64
grubby-8.28-25.el7.x86_64
[...]
# rpm -qi unzip
Name        : unzip
Version     : 6.0
Release     : 19.el7
Architecture: x86_64
Install Date: Sun 25 Aug 2019 05:14:39 PM EDT
Size        : 373986
License     : BSD
Signature   : RSA/SHA256, Wed 25 Apr 2018 07:50:02 AM EDT, Key ID 24c6a8a7f4a80eb5
Source RPM  : unzip-6.0-19.el7.src.rpm
Summary     : A utility for unpacking zip files
# rpm -ql unzip
/usr/bin/funzip
/usr/bin/unzip
/usr/bin/zipinfo
/usr/share/doc/unzip-6.0/README
/usr/share/man/man1/unzip.1.gz
# rpm -qf /usr/bin/unzip
unzip-6.0-19.el7.x86_64

For a downloaded .rpm that is not installed yet, add -p: rpm -qi PACKAGE becomes rpm -qip FILE, and rpm -ql PACKAGE becomes rpm -qlp FILE:

# rpm -qi unzip                                 # info about installed unzip
# rpm -qip atom.rpm                             # info about an uninstalled .rpm file
# rpm -ql unzip                                 # files installed by unzip
# rpm -qlp atom.rpm                             # files inside an uninstalled .rpm file
# rpm -qip atom.x86_64.rpm
Name        : atom
Version     : 1.40.0
Install Date: (not installed)
Signature   : (none)
Summary     : A hackable text editor for the 21st Century.
# rpm -qlp atom.x86_64.rpm
/usr/bin/apm
/usr/bin/atom
/usr/share/applications/atom.desktop
(listing goes on)

rpm: integrity and signatures

rpm -V compares the files of an installed package with the original package. With no output, nothing changed. Use -Vv for verbose output. Here /usr/bin/tmux was edited by hand:

# rpm -V tmux
S.5....T.    /usr/bin/tmux

Each letter is a test that failed, and a dot means the test passed:

Code Meaning
S size differs
M mode differs (permissions and file type)
5 digest (formerly MD5 sum) differs, so the content changed
D device major/minor number mismatch
L symbolic link path mismatch
U user ownership differs
G group ownership differs
T modification time differs
P capabilities differ

rpm -K checks a package file before you install it: its digests and its signature. OK everywhere means the file is valid and was not changed:

# rpm -Kv breezy-3.2.1-3.fc36.x86_64.rpm
breezy-3.2.1-3.fc36.x86_64.rpm:
    Header V4 RSA/SHA256 Signature, key ID 38ab71f4: OK
    Header SHA256 digest: OK
    Header SHA1 digest: OK
    Payload SHA256 digest: OK
    V4 RSA/SHA256 Signature, key ID 38ab71f4: OK
    MD5 digest: OK

rpm2cpio: extract files without installing

cpio is an archive format, like tar or zip. rpm2cpio turns an .rpm into a cpio archive, and cpio extracts it. This is useful when you need one file from a package (a default configuration file, for example) without installing it:

# rpm2cpio breezy-3.2.1-3.fc36.x86_64.rpm > breezy.cpio
# cpio -idv < breezy.cpio
./usr/bin/brz
./usr/bin/bzr
./usr/bin/bzr-receive-pack
[...]
# rpm2cpio breezy-3.2.1-3.fc36.x86_64.rpm | cpio -idv     # the same in one line

cpio -i extracts, -d creates the directories, -v lists the files.

yum

yum started as YUP (Yellow Dog Updater) on the Yellow Dog Linux distribution, and grew to manage packages on Fedora, CentOS, RHEL and Oracle Linux. It does on RPM systems what apt does on Debian: search, install, update and remove packages, with automatic dependency resolution, for one package or the whole system.

The format is yum [OPTIONS] [COMMAND] [PACKAGE_NAME]. The most useful option is -y, which answers "yes" to every question.

Searching looks in package names and summaries (search all looks everywhere):

# yum search 7zip
=========================== N/S matched: 7zip ============================
p7zip-plugins.x86_64 : Additional plugins for p7zip
p7zip.x86_64 : Very high compression ratio file archiver
p7zip-doc.noarch : Manual documentation and contrib directory
p7zip-gui.x86_64 : 7zG - 7-Zip GUI version
  Name and summary matches only, use "search all" for everything.

Installing fetches the package and its dependencies from the repositories:

# yum install p7zip
Resolving Dependencies
--> Running transaction check
---> Package p7zip.x86_64 0:16.02-10.el7 will be installed
--> Finished Dependency Resolution
==========================================================================
 Package      Arch        Version            Repository     Size
==========================================================================
Installing:
 p7zip        x86_64      16.02-10.el7       epel           604 k

Transaction Summary
==========================================================================
Install  1 Package
Total download size: 604 k
Installed size: 1.7 M
Is this ok [y/d/N]:

Updating, checking and removing:

# yum update wget                               # upgrade one package
# yum update                                    # upgrade every package that has an update
# yum check-update                              # only list available updates
# yum update 'cal*'                             # wildcards work too
# yum remove wget

Which package provides a file? Remember the GIMP error above: rpm said libgimpui-2.0.so.0 was missing, but not which package has it. yum whatprovides (or provides) answers, and it works for files already on your system too:

# yum whatprovides libgimpui-2.0.so.0
2:gimp-libs-2.8.22-1.el7.i686 : GIMP libraries
Repo        : base
Matched from:
Provides    : libgimpui-2.0.so.0
# yum whatprovides /etc/hosts
setup-2.8.71-10.el7.noarch : A set of system configuration and setup files
Repo        : base
Matched from:
Filename    : /etc/hosts

So yum install gimp-libs fixes the first problem, and /etc/hosts comes from the setup package.

Information about a package:

# yum info firefox
Installed Packages
Name         : firefox
Version      : 69.0.1
Release      : 3.fc30
Architecture : x86_64
Size         : 268 M
Repository   : @System
From repo    : updates
Summary      : Mozilla Firefox Web browser
License      : MPLv1.1 or GPLv2+ or LGPLv2+

All the yum commands to know:

Command What it does
install install a package and its dependencies
reinstall install a package again
remove remove a package
update refresh repository data and upgrade the named package, or all packages
upgrade like update, and also removes obsolete packages
check-update list available updates without installing them
search search package names and summaries
info show information about a package
list list packages (installed, available or both)
provides / whatprovides find the package that provides a file. E.g. yum provides /etc/hosts tells you setup owns it
deplist show the dependencies of a package
localinstall install a local .rpm file, getting its dependencies from the repositories
localupdate update from a local .rpm file
groupinstall install a group of packages, like yum groupinstall "KDE Plasma Workspaces"
history show the history of yum transactions

yumdownloader downloads .rpm files from the repositories without installing them. --resolve also downloads the dependencies:

# yumdownloader --resolve bzr

yum configuration and repositories

The main configuration file is /etc/yum.conf:

# cat /etc/yum.conf
[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=3

Repositories are .repo files in /etc/yum.repos.d/, one or more repositories per file, like CentOS-Base.repo or fedora.repo:

# cat /etc/yum.repos.d/fedora.repo
[fedora]
name=Fedora $releasever - $basearch
#baseurl=http://download.example/pub/fedora/linux/releases/$releasever/Everything/$basearch/os/
metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch
enabled=1
countme=1
metadata_expire=7d
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
skip_if_unavailable=False

[fedora-debuginfo]
name=Fedora $releasever - $basearch - Debug
enabled=0
...
Field Meaning
[fedora] the repository id
name a readable name
baseurl or metalink where the packages are downloaded from
enabled 1 active, 0 ignored
gpgcheck 1 checks package signatures before installing
gpgkey the key used to check the signatures

You can add a repository by creating a .repo file there, or at the end of /etc/yum.conf, but the recommended tool is yum-config-manager:

# yum-config-manager --add-repo https://rpms.remirepo.net/enterprise/remi.repo
adding repo from: https://rpms.remirepo.net/enterprise/remi.repo
grabbing file https://rpms.remirepo.net/enterprise/remi.repo to /etc/yum.repos.d/remi.repo
repo saved to /etc/yum.repos.d/remi.repo
# yum repolist all
repo id                 repo name                        status
updates/7/x86_64        CentOS-7 - Updates               enabled: 2,500
updates-source/7        CentOS-7 - Updates Sources       disabled
# yum-config-manager --add-repo https://example.com/my.repo   # add a new repo
# yum-config-manager --disable updates
# yum-config-manager --enable updates

Disabled repositories are ignored. To enable or disable one, use the part of the repo id before the first /: updates, not updates/7/x86_64.

yum keeps downloaded packages and metadata in a cache (usually /var/cache/yum), which grows over time:

# yum clean packages                            # delete downloaded packages
# yum clean metadata                            # delete repository metadata

dnf

dnf is the package manager of Fedora, a fork of yum, so most commands are the same. On Fedora, yum commands are even translated to dnf for you.

Task Command
search dnf search PATTERN
information dnf info PACKAGE
install dnf install PACKAGE
remove dnf remove PACKAGE
upgrade one package, or all dnf upgrade PACKAGE, dnf upgrade
which package provides a file dnf provides FILENAME
list installed packages dnf list --installed
list the files of a package dnf repoquery -l PACKAGE
help for a command dnf help install

Repositories work the same way, in .repo files in /etc/yum.repos.d/:

# dnf repolist                                  # --enabled or --disabled to filter
repo id               repo name                              status
*fedora               Fedora 30 - x86_64                     56,582
*updates              Fedora 30 - x86_64 - Updates           12,774
# dnf config-manager --add_repo URL             # added repos are enabled by default
# dnf config-manager --set-enabled REPO_ID
# dnf config-manager --set-disabled REPO_ID
dnf quick reference (same syntax as yum for most operations):

  dnf search PATTERN                     # search
  dnf info PACKAGE                       # package info
  dnf install PACKAGE                    # install
  dnf remove PACKAGE                     # remove
  dnf upgrade PACKAGE                    # upgrade one package
  dnf upgrade                            # upgrade everything
  dnf provides FILENAME                  # which package provides this file?
  dnf list --installed                   # all installed packages
  dnf repoquery -l PACKAGE               # list files inside a package
  dnf repolist                           # list repos
  dnf config-manager --add_repo URL      # add a repo
  dnf config-manager --set-enabled REPO  # enable a repo
  dnf config-manager --set-disabled REPO # disable a repo

zypper

SUSE Linux and openSUSE use the ZYpp engine. You talk to it with the command-line tool zypper or the graphical YaST. Like apt and yum, zypper installs, updates and removes packages with automatic dependency resolution. Most commands have a short form: zypper se instead of zypper search, se for search, in for install, rm for remove.

Refresh the repository metadata so zypper knows the latest packages. Some repositories have auto-refresh turned on, so they refresh by themselves before a query or install:

# zypper refresh
Repository 'Non-OSS Repository' is up to date.
Repository 'Main Repository' is up to date.
All repositories have been refreshed.

Search. In the S column, i means installed. -i searches only installed packages (with no name, it lists all installed packages), -u only packages that are not installed:

# zypper se gnumeric
S | Name           | Summary                          | Type
--+----------------+----------------------------------+--------
  | gnumeric       | Spreadsheet Application          | package
  | gnumeric-doc   | Documentation files for Gnumeric | package
# zypper se -i firefox
S | Name                               | Summary                 | Type
--+------------------------------------+-------------------------+--------
i | MozillaFirefox                     | Mozilla Firefox Web B-> | package
i | MozillaFirefox-translations-common | Common translations f-> | package

Install, update and remove:

# zypper in unrar
The following NEW package is going to be installed:
  unrar
1 new package to install.
Continue? [y/n/v/...? shows all options] (y): y
(1/1) Installing: unrar-5.7.5-lp151.1.1.x86_64 .....................[done]
# zypper in /home/john/newpackage.rpm           # a local .rpm, dependencies from the repositories
# zypper list-updates                           # only list available updates
# zypper update                                 # install the updates
# zypper rm unrar

Removing a package also removes every package that depends on it, and zypper lists them first:

# zypper rm libgimp-2_0-0
The following 6 packages are going to be REMOVED:
  gimp gimp-help gimp-lang gimp-plugins-python libgimp-2_0-0
  libgimpui-2_0-0
6 packages to remove.
After the operation, 98.0 MiB will be freed.
Continue? [y/n/v/...? shows all options] (y):

Which package contains a file, and information about a package:

# zypper se --provides /usr/lib64/libgimpmodule-2.0.so.0
S | Name          | Summary                                      | Type
--+---------------+----------------------------------------------+--------
i | libgimp-2_0-0 | The GNU Image Manipulation Program - Libra-> | package
# zypper info gimp
Information for package gimp:
-----------------------------
Repository     : Main Repository
Name           : gimp
Version        : 2.8.22-lp151.4.6
Arch           : x86_64
Vendor         : openSUSE
Installed Size : 29.1 MiB
Installed      : Yes (automatically)
Status         : up-to-date
Source package : gimp-2.8.22-lp151.4.6.src

Repositories. zypper repos (or lr) lists them. The alias in the second column is the name you use in other commands:

# zypper repos
#  | Alias        | Name               | Enabled | GPG Check | Refresh
---+--------------+--------------------+---------+-----------+--------
 2 | repo-debug   | Debug Repository   | No      | ----      | ----
 6 | repo-non-oss | Non-OSS Repository | Yes     | (r ) Yes  | Yes
 7 | repo-oss     | Main Repository    | Yes     | (r ) Yes  | Yes
# zypper modifyrepo -d repo-non-oss             # disable
# zypper modifyrepo -e repo-non-oss             # enable
# zypper modifyrepo -F repo-non-oss             # turn auto-refresh off
# zypper modifyrepo -f repo-non-oss             # turn auto-refresh on
# zypper addrepo http://packman.inode.at/suse/openSUSE_Leap_15.1/ packman
# zypper removerepo packman

The general forms:

# zypper addrepo URL ALIAS                      # add a repository
# zypper removerepo ALIAS                       # remove a repository
# zypper modifyrepo --enable ALIAS              # enable a repo
# zypper modifyrepo --disable ALIAS             # disable a repo

addrepo takes the URL and an alias. New repositories are enabled by default: add -f to turn on auto-refresh, or -d to add it disabled.

zypper command What it does
refresh refresh the repository information
search (se) search packages, -i installed, -u not installed, --provides by file
install (in) install a package, or a local .rpm
remove (rm) remove a package and the packages that depend on it
update update installed packages
list-updates show available updates
info show package information
what-provides show which package owns a file
packages list all packages, or those of one repository
repos (lr) list repositories
addrepo, removerepo, modifyrepo manage repositories
verify check a package and its dependencies
help general help

Other tools

Tool Used by Description
dnf Fedora (default) fork of yum with improved performance. Most yum commands work identically. Pre-installed on Fedora
YaST SUSE graphical system administration tool, including package management
PackageKit KDE and GNOME desktops graphical package management used by desktop environments

Summary

I have a Red Hat-based (or SUSE) Linux system where software is distributed as .rpm packages. Like Debian's two-layer system, there's rpm at the bottom (works on individual files, no dependency resolution) and yum/dnf/zypper on top (works with repositories, resolves dependencies automatically).

For rpm, the key actions are -U (install or upgrade, the most common), -F (only upgrade), -i (only install), with -vh for progress, and -e (erase/remove, without asking); they stop on dependency problems that rpm cannot solve. I query with -q and sub-options like -qa for all packages, -qi for information, -ql for the file list, -qc for configuration files, -qR for dependencies and -qf for file ownership, and the -p modifier switches queries from the installed database to an uninstalled .rpm file. -V verifies installed files against their original state (letters like S, 5 and T show what changed), and -K checks a .rpm file's integrity and signature before installing. rpm2cpio | cpio -idv extracts files from a .rpm without installing it, which is useful for pulling a single config file from a package during recovery.

For yum/dnf, the commands mirror what apt-get does on Debian: search, install, update, check-update, upgrade, remove, info and provides (or whatprovides), with -y to skip questions. Settings live in /etc/yum.conf and repositories in .repo files in /etc/yum.repos.d/ with enabled and gpgcheck; yum-config-manager adds or toggles repositories, yum clean empties the cache and yumdownloader fetches packages. dnf is the Fedora fork with almost the same commands plus dnf config-manager. SUSE uses zypper instead, with shortened commands: refresh, se for search (-i, -u, --provides), in for install, rm for remove (which also removes dependent packages), info, repos, addrepo and modifyrepo.