Software ManagementLesson 2 of 4
Installing, updating and removing software with DNF
Search, install, update and remove packages and groups, install a local RPM with its dependencies, and undo a change.
dnfdnf installdnf removednf upgradednf searchdnf infodnf providesdnf groupdnf historydnf download
After this lesson you can
- Find, install, update and remove packages, and read what DNF is about to do before confirming.
- Install a local RPM file so its dependencies come from the repositories.
- Work with package groups, review the transaction history and undo a transaction.
The idea
rpm installs a package file and stops. DNF is the package manager on top: it reads repositories (catalogues of packages), works out dependencies, downloads everything needed and installs it as one transaction that it records in a history. On RHEL 10 the dnf command is DNF 4, and yum is kept as an alias.
The daily commands:
| Task | Command |
|---|---|
| Find by name or description | dnf search keyword |
| Which package provides a file or command | dnf provides '*/name' |
| Details of a package | dnf info name |
| Install | dnf install name... |
| Install from a local file | dnf install ./file.rpm |
| Remove | dnf remove name |
| List updates | dnf check-update |
| Update one package / everything | dnf upgrade name / dnf upgrade |
| Packages installed / available | dnf list installed / dnf list available |
| Groups | dnf group list, dnf group install "Name" |
| History | dnf history, dnf history info N, dnf history undo N |
Before DNF acts it prints the transaction summary: what will be installed, upgraded or removed, and how large the download is. Read it. -y answers yes to the question, which is right in scripts and in a hurry, but then nothing stops you removing 40 packages by mistake. Removing a package also removes anything that depends on it, and dnf remove shows those too.
Try it
dnf provides '*/bin/tree'
tree-2.1.0-6.el10.x86_64 : File system tree viewer
Repo : rhel-10-for-x86_64-appstream-rpms
Matched from:
Filename : /usr/bin/tree
sudo dnf install -y tree
rpm -q tree
sudo dnf remove -y tree
Installed:
tree-2.1.0-6.el10.x86_64
Complete!
tree-2.1.0-6.el10.x86_64
Removed:
tree-2.1.0-6.el10.x86_64
Complete!
Install a downloaded file the safe way
mkdir -p ~/lab/rpms && cd ~/lab/rpms
dnf download tree
sudo dnf install -y ./tree-*.rpm
tree-2.1.0-6.el10.x86_64.rpm 1.2 MB/s | 56 kB 00:00
Installed:
tree-2.1.0-6.el10.x86_64
Complete!
Updates
dnf check-update; echo "exit=$?"
dnf updateinfo list security | head -3
kernel.x86_64 6.12.0-55.14.1.el10_0 rhel-10-for-x86_64-baseos-rpms
tzdata.noarch 2025b-1.el10 rhel-10-for-x86_64-baseos-rpms
exit=100
RHSA-2026:1234 Important/Sec. openssl-3.2.2-1.el10_0.x86_64
RHSA-2026:1250 Moderate/Sec. tzdata-2025b-1.el10.noarch
dnf check-update exits 100 if updates exist, 0 if none, 1 on error, which is handy in scripts. dnf upgrade with no name updates everything; keep a kernel or two (installonly_limit=3 in /etc/dnf/dnf.conf) so you can boot the old one if the new one fails. A new kernel only runs after a reboot.
Groups and history
dnf group list | head -6
sudo dnf group install -y "Development Tools"
Available Environment Groups:
Server with GUI
Server
Minimal Install
Available Groups:
Development Tools
Container Management
dnf history | head -4
sudo dnf history undo 12
ID | Command line | Date and time | Action(s) | Altered
--------------------------------------------------------------------------------------
12 | install -y tree | 2026-11-03 10:41 | Install | 1
11 | upgrade -y tzdata | 2026-11-03 10:20 | Upgrade | 1
Going further
dnf install --downloadonly fetches without installing. dnf autoremove deletes packages that were only installed as dependencies and are no longer needed. dnf repoquery --requires NAME and dnf repoquery --whatrequires NAME show dependency relationships. dnf needs-restarting -r tells you if a reboot is needed after updates, and dnf versionlock pins a package at a version. DNF logs to /var/log/dnf.log and /var/log/dnf.rpm.log, the first place to look when a transaction fails.
Practice
0 of 6 done
Do these on your own system. They get harder. Check each result, then tick it off.
- Warm-up
Find a package and read about it
Search the repositories for a package that provides the
treecommand, show its details and say which repository it comes from.Check your result
dnf info treeshows Name, Version, Repository (for examplerhel-10-for-x86_64-appstream-rpmsorappstream) and Summary.Hint
dnf search tree,dnf info tree, ordnf provides /usr/bin/tree.Solution
dnf search tree | head dnf info tree dnf provides /usr/bin/tree - Practice
Install, use, remove
Install
treenon-interactively. Confirm withrpm -q. Remove it and confirm it is gone. Explain what-ydoes and why you should read the transaction summary first when not using it.Check your result
rpm -q treeshows a version after install, andpackage tree is not installedafter removal.Hint
sudo dnf install -y tree,sudo dnf remove -y tree.Solution
sudo dnf install -y tree rpm -q tree tree -L 1 /etc | head -5 sudo dnf remove -y tree rpm -q tree - Practice
Install a downloaded RPM file
Download the RPM for
treeinto~/lab/rpms(dnf download), then install from the file using DNF so that any dependencies would be resolved from the repositories. Do not userpm -ivh. Remove it again.Check your result
rpm -q treeshows it installed aftersudo dnf install ./tree-*.rpm.Hint
Give
dnf installa path that contains a slash, like./file.rpm; otherwise it searches repositories for a package of that name.Solution
mkdir -p ~/lab/rpms && cd ~/lab/rpms dnf download tree sudo dnf install -y ./tree-*.rpm rpm -q tree sudo dnf remove -y tree - Practice
See what needs updating
List the packages for which updates are available, show only security updates, then update a single package (
tzdataor any package that is listed) without touching the rest of the system.Check your result
dnf check-updateexits with 100 when updates exist.dnf upgrade -y tzdatachanges only that package (and anything it requires).Hint
dnf check-update,dnf updateinfo list security,dnf upgrade PACKAGE.Solution
dnf check-update; echo "exit=$?" dnf updateinfo list security | head sudo dnf upgrade -y tzdata - Practice
Install a group, then see it as a set
List the available package groups, show which packages are in the
Development Toolsgroup, and install the mandatory and default members of that group. Afterwards remove the group again.Check your result
dnf group listshowsDevelopment Tools.dnf group info 'Development Tools'lists members. After installgcc --versionworks; after removalrpm -q gccsays not installed (unless something else needs it).Hint
Quote group names that contain a space.
dnf group install "Development Tools"anddnf group remove.Solution
dnf group list dnf group info "Development Tools" sudo dnf group install -y "Development Tools" gcc --version | head -1 sudo dnf group remove -y "Development Tools" - Challenge
Undo a change
Install
tree, find that transaction in the history, show what it did, and undo it. Then identify, from the history alone, who ran the very first transaction on this machine and when.Check your result
dnf historylists the install with an ID.dnf history info IDshowsPackages Alteredwithtree. Aftersudo dnf history undo IDthe package is removed.Hint
dnf history,dnf history info N,dnf history undo N. The last entry in the list is the oldest.Solution
sudo dnf install -y tree dnf history | head -4 id=$(dnf history | awk 'NR>2 {print $1; exit}') dnf history info "$id" sudo dnf history undo -y "$id" rpm -q tree dnf history | tail -3