Skip to content

package management

(Written by Paul Cobbaut, https://github.com/paulcobbaut/, with contributions by: Alex M. Schapelle, https://github.com/zero-pytagoras/, Bert Van Vreckem https://github.com/bertvv/)

Most Linux distributions have a package management system with online repositories containing thousands of packages. This makes it very easy to install, update and remove applications, operating system components, documentation and much more.

We first discuss the Debian package format .deb and its tools dpkg, apt-get and apt. This should be similar on Debian, Ubuntu, Mint and all derived distributions.

Then we take a look at the Red Hat package format .rpm and its tools rpm and dnf. This should be similar on Red Hat, Fedora, AlmaLinux and all derived distributions.

package terminology

repository

A lot of software and documentation for your Linux distribution is available as packages in one or more centrally distributed repositories. The packages in such a repository are tested and very easy to install (or remove) with a graphical or command line installer.

.deb packages

Debian, Ubuntu, Mint and all derivatives of Debian and Ubuntu use .deb packages. To manage software on these systems, you can use apt or apt-get, both these tools are a front end for dpkg.

.rpm packages

Red Hat, Fedora, CentOS, OpenSUSE, Mandriva, Red Flag and others use .rpm packages. The tools to manage software packages on these systems are dnf and rpm.

dependency

Some packages need other packages to function. Tools like apt-get, apt and dnf will install all dependencies you need. When using dpkg or rpm, or when building from source, you will need to install dependencies yourself.

open source

These repositories contain a lot of independent open source software. Often the source code is customized to integrate better with your distribution. Most distributions also offer this modified source code as a package in one or more source repositories.

You are free to go to the project website itself (samba.org, apache.org, github.com ...) and download the vanilla (= without the custom distribution changes) source code.

GUI software management

End users have several graphical applications available via the desktop (look for add/remove software or something similar).

Below a screenshot of Ubuntu Software Center running on Ubuntu 12.04. Graphical tools are not discussed in this book.

deb package management

about deb

Most people use apt or apt-get (APT = Advanced Package Tool) to manage their Debian/Ubuntu family of Linux distributions. Both are a front end for dpkg and are themselves a back end for synaptic and other graphical tools.

dpkg -l

The low level tool to work with .deb packages is dpkg. Among other things, you can use dpkg to list all installed packages on a Debian server.

student@debian:~$ dpkg -l | wc -l
365

Compare this to the same list on a Linux Mint system with a graphical desktop installed.

student@mint:~$ dpkg -l | wc -l
2118

dpkg -l $package

Here is an example on how to get information on an individual package. The ii at the beginning means the package is installed.

root@debian:~# dpkg -l rsync | tail -1 | tr -s  ' '
ii rsync 3.2.7-1 amd64 fast, versatile, remote (and local) file-copying tool

dpkg -S

You can find the package responsible for installing a certain file on your computer using dpkg -S. This example shows how to find the package for three files on a typical Debian server.

student@debian:~$ dpkg -S /usr/share/doc/tmux/ /etc/ssh/ssh_config /sbin/ifconfig
dpkg-query: no path found matching pattern /usr/share/doc/tmux/
openssh-client: /etc/ssh/ssh_config
net-tools: /sbin/ifconfig

dpkg -L

In reverse, you can also get a list of all files that have been installed by a certain program. Below is the list for the curl package.

student@debian:~$ dpkg -L curl
/.
/usr
/usr/bin
/usr/bin/curl
/usr/share
/usr/share/doc
/usr/share/doc/curl
/usr/share/doc/curl/changelog.Debian.gz
/usr/share/doc/curl/changelog.gz
/usr/share/doc/curl/copyright
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/curl.1.gz
/usr/share/zsh
/usr/share/zsh/vendor-completions
/usr/share/zsh/vendor-completions/_curl

dpkg

You could use dpkg -i to install a package and dpkg -r to remove a package, but you\'d have to manually download the packge and keep track of dependencies. Using apt-get or apt is much easier.

apt-get

Debian has been using apt-get to manage packages since 1998. Today Debian and many Debian-based distributions still actively support apt-get, though some experts claim apt, released in 2014, is better at handling dependencies than apt-get.

Both commands use the same configuration files and can be used alternately; whenever you see apt-get in documentation, feel free to type apt.

We will start with apt-get and discuss apt in the next section.

apt-get update

When typing apt-get update you are downloading the names, versions and short description of all packages available on all configured repositories for your system. Remark that you need to be root to run this command.

student@debian:~$ apt-get update
Reading package lists... Done
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
student@debian:~$ sudo apt-get update
Hit:1 http://security.debian.org/debian-security bookworm-security InRelease
Hit:2 http://httpredir.debian.org/debian bookworm InRelease
Hit:3 http://httpredir.debian.org/debian bookworm-updates InRelease
Reading package lists... Done

In the example below you can see an interaction with an Ubuntu system. Some repositories are at the url be.archive.ubuntu.com because this computer was installed in Belgium. This mirror URL can be different for you.

student@ubuntu:~$ sudo apt-get update
Ign http://be.archive.ubuntu.com precise InRelease
Ign http://extras.ubuntu.com precise InRelease
Ign http://security.ubuntu.com precise-security InRelease            
Ign http://archive.canonical.com precise InRelease                                         
Ign http://be.archive.ubuntu.com precise-updates InRelease                                 
...
Hit http://be.archive.ubuntu.com precise-backports/main Translation-en                                                             
Hit http://be.archive.ubuntu.com precise-backports/multiverse Translation-en                                                       
Hit http://be.archive.ubuntu.com precise-backports/restricted Translation-en                                                       
Hit http://be.archive.ubuntu.com precise-backports/universe Translation-en                                                         
Fetched 13.7 MB in 8s (1682 kB/s)                                                                                                  
Reading package lists... Done
student@ubuntu:~$

Tips:

  • Run apt-get update every time before performing other package operations to ensure your metadata is up-to-date.
  • Since the package repositories are hosted on web servers, you can open any repository URL in your browser to see how the repository is structured.

apt-get upgrade

One of the nicest features of apt-get is that it allows for a secure update of all software currently installed on your computer with just one command.

student@debian:~$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

The above transcript shows that all software is updated to the latest version available for my distribution. Below is an example of a system with software that can be updated. Some lines were ommitted for brevity.

student@debian:~$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  linux-image-amd64
The following packages will be upgraded:
  base-files bind9-dnsutils bind9-host bind9-libs cryptsetup cryptsetup-bin libcryptsetup12 libgnutls30 libnss-systemd libpam-systemd libsystemd-shared libsystemd0 libudev1 systemd systemd-sysv
  systemd-timesyncd tar tzdata udev usr-is-merged
20 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Need to get 13.0 MB of archives.
After this operation, 75.8 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://security.debian.org/debian-security bookworm-security/main amd64 bind9-host amd64 1:9.18.24-1 [305 kB]
[...]
Get:20 http://httpredir.debian.org/debian bookworm/main amd64 cryptsetup amd64 2:2.6.1-4~deb12u2 [213 kB]
Fetched 13.0 MB in 1s (20.3 MB/s)
Reading changelogs... Done
Preconfiguring packages ...
(Reading database ... 29205 files and directories currently installed.)
Preparing to unpack .../base-files_12.4+deb12u5_amd64.deb ...
Unpacking base-files (12.4+deb12u5) over (12.4+deb12u4) ...
Setting up base-files (12.4+deb12u5) ...
Installing new version of config file /etc/debian_version ...
[...]
Preparing to unpack .../5-cryptsetup_2%3a2.6.1-4~deb12u2_amd64.deb ...
Unpacking cryptsetup (2:2.6.1-4~deb12u2) over (2:2.6.1-4~deb12u1) ...
Setting up systemd-sysv (252.22-1~deb12u1) ...
[...]
Setting up bind9-dnsutils (1:9.18.24-1) ...
Processing triggers for initramfs-tools (0.142) ...
update-initramfs: Generating /boot/initrd.img-6.1.0-17-amd64
[...]
Processing triggers for mailcap (3.70+nmu1) ...

Tip: Have you noticed that almost every time that you update software on Windows, you are asked to reboot your computer? This is not the case with Linux! The only time you need to reboot is when you update the kernel.

apt-get clean

apt-get keeps a copy of downloaded packages in /var/cache/apt/archives, as can be seen in this screenshot.

student@debian:~$ ls /var/cache/apt/archives/ | head
base-files_12.4+deb12u5_amd64.deb
bind9-dnsutils_1%3a9.18.24-1_amd64.deb
bind9-host_1%3a9.18.24-1_amd64.deb
bind9-libs_1%3a9.18.24-1_amd64.deb
cryptsetup_2%3a2.6.1-4~deb12u2_amd64.deb
cryptsetup-bin_2%3a2.6.1-4~deb12u2_amd64.deb
libcryptsetup12_2%3a2.6.1-4~deb12u2_amd64.deb
libgnutls30_3.7.9-2+deb12u2_amd64.deb
libnss-systemd_252.22-1~deb12u1_amd64.deb
libpam-systemd_252.22-1~deb12u1_amd64.deb

Running apt-get clean removes all .deb files from that directory.

student@debian:~$ sudo apt-get clean
student@debian:~$ ls /var/cache/apt/archives/*.deb
ls: cannot access /var/cache/apt/archives/*.deb: No such file or directory

Use apt-cache search to search for availability of a package. Here we look for rsync.

student@debian:~$ apt-cache search rsync | grep '^rsync'
rsync - fast, versatile, remote (and local) file-copying tool
rsyncrypto - rsync friendly encryption

apt-get install

You can install one or more applications by appending their name behind apt-get install. The following example shows how to install the tftp-hpa package (a TFTP server).

student@debian:~$ sudo apt-get install tftpd-hpa
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Suggested packages:
  pxelinux
The following NEW packages will be installed:
  tftpd-hpa
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 41.9 kB of archives.
After this operation, 117 kB of additional disk space will be used.
Get:1 http://httpredir.debian.org/debian bookworm/main amd64 tftpd-hpa amd64 5.2+20150808-1.4 [41.9 kB]
Fetched 41.9 kB in 0s (241 kB/s)
Preconfiguring packages ...
Selecting previously unselected package tftpd-hpa.
(Reading database ... 29179 files and directories currently installed.)
Preparing to unpack .../tftpd-hpa_5.2+20150808-1.4_amd64.deb ...
Unpacking tftpd-hpa (5.2+20150808-1.4) ...
Setting up tftpd-hpa (5.2+20150808-1.4) ...
Processing triggers for man-db (2.11.2-2) ...

The apt-get command will ask the user to confirm the installation of the package by pressing "y" and ENTER. You can use the -y option to automatically answer yes to all questions.

The following example installs the vim package (VI iMproved, a powerful text editor for the terminal). Remark that some additional packages are installed as dependencies!

student@debian:~$ sudo apt-get install -y vim
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libgpm2 libsodium23 vim-runtime
Suggested packages:
  gpm ctags vim-doc vim-scripts
The following NEW packages will be installed:
  libgpm2 libsodium23 vim vim-runtime
0 upgraded, 4 newly installed, 0 to remove and 1 not upgraded.
Need to get 8,768 kB of archives.
After this operation, 41.5 MB of additional disk space will be used.
[...]
Setting up libsodium23:amd64 (1.0.18-1) ...
Setting up libgpm2:amd64 (1.20.7-10+b1) ...
Setting up vim-runtime (2:9.0.1378-2) ...
Setting up vim (2:9.0.1378-2) ...
[...]
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+deb12u4) ...

apt-get remove

You can remove one or more applications by appending their name behind apt-get remove.

student@debian:~$ sudo apt-get remove tftpd-hpa 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  tftpd-hpa
0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
After this operation, 117 kB disk space will be freed.
Do you want to continue? [Y/n] y 
(Reading database ... 29194 files and directories currently installed.)
Removing tftpd-hpa (5.2+20150808-1.4) ...
Processing triggers for man-db (2.11.2-2) ...

If we use dpkg -l to check the status of the tftpd-hpa package, we see that it is removed, some configuration (rc) files are left on the system. Indeed, the configuration file /etc/init/tftpd-hpa.conf is not removed! We'll solve this in the next section.

student@debian:~$ dpkg -l tftpd-hpa | tail -1
rc  tftpd-hpa      5.2+20150808-1.4 amd64        HPA's tftp server
student@debian:~$ ls -l /etc/init/tftpd-hpa.conf 
-rw-r--r-- 1 root root 980 Oct 25  2022 /etc/init/tftpd-hpa.conf

The example below shows how to remove the vim package. Note that dependencies are not removed! You can execute sudo apt autoremove afterwards (as is suggested by the output of the command!) to remove those as well.

student@debian:~$ sudo apt-get remove vim
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libsodium23 vim-runtime
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
  vim
0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
After this operation, 3,738 kB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 31257 files and directories currently installed.)
Removing vim (2:9.0.1378-2) ...
[...]
student@debian:~$ sudo apt-get autoremove
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  libsodium23 vim-runtime
0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.
After this operation, 37.7 MB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 31247 files and directories currently installed.)
Removing libsodium23:amd64 (1.0.18-1) ...
Removing vim-runtime (2:9.0.1378-2) ...
Removing 'diversion of /usr/share/vim/vim90/doc/help.txt to /usr/share/vim/vim90/doc/help.txt.vim-tiny by vim-runtime'
Removing 'diversion of /usr/share/vim/vim90/doc/tags to /usr/share/vim/vim90/doc/tags.vim-tiny by vim-runtime'
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+deb12u4) ...

apt-get purge

You can purge one or more applications by appending their name behind apt-get purge. Purging will also remove all existing configuration files related to that application. The screenshot shows how to purge the tftpd-hpa package.

student@debian:~$ ls -l /etc/init/tftpd-hpa.conf 
-rw-r--r-- 1 root root 980 Oct 25  2022 /etc/init/tftpd-hpa.conf
student@debian:~$ sudo apt-get purge tftpd-hpa
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  tftpd-hpa*
0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
(Reading database ... 29182 files and directories currently installed.)
Purging configuration files for tftpd-hpa (5.2+20150808-1.4) ...
student@debian:~$ ls -l /etc/init/tftpd-hpa.conf 
ls: cannot access '/etc/init/tftpd-hpa.conf': No such file or directory

Note that dpkg has no information about a purged package!

student@debian:~$ dpkg -l tftpd-hpa | tail -1 | tr -s ' ' 
dpkg-query: no packages found matching tftpd-hpa

apt

Nowadays, most people use apt for package management on Debian, Mint and Ubuntu systems. That does not mean that apt-get is no longer useful. In scripts, it is actually recommended to use apt-get because its options and behaviour are more stable and predictable than apt. For interactive use, apt is more user-friendly.

To synchronize with the repositories.

sudo apt update

To patch and upgrade all software to the latest version on Debian.

sudo apt upgrade

To patch and upgrade all software to the latest version on Ubuntu and Mint.

sudo apt safe-upgrade

To install an application with all dependencies.

sudo apt install $package

To search the repositories for applications that contain a certain string in their name or description.

apt search $string

To remove an application.

sudo apt remove $package

To remove an application and all configuration files.

sudo apt purge $package

/etc/apt/sources.list

Both apt-get and apt use the same configuration information in /etc/apt/. The main configuration file is /etc/apt/sources.list and the directory /etc/apt/sources.list.d/ contains additional files. These contain a list of http or ftp sources where packages for the distribution can be downloaded. Third party software vendors may provide their own package repositories for Debian or Ubuntu. These repositories are typically added through a new file in /etc/apt/sources.list.d/.

This is what that list looks like on a Debian server system shortly after installation.

student@debian:~$ cat /etc/apt/sources.list
deb http://httpredir.debian.org/debian/ bookworm main non-free-firmware
deb-src http://httpredir.debian.org/debian/ bookworm main non-free-firmware

deb http://security.debian.org/debian-security bookworm-security main non-free-firmware
deb-src http://security.debian.org/debian-security bookworm-security main non-free-firmware

# bookworm-updates, to get updates before a point release is made;
deb http://httpredir.debian.org/debian/ bookworm-updates main non-free-firmware
deb-src http://httpredir.debian.org/debian/ bookworm-updates main non-free-firmware

If you use Linux as a daily driver, you may end up with a repository list with many more entries, like on this Ubuntu system:

student@ubuntu:~$ wc -l /etc/apt/sources.list
63 /etc/apt/sources.list

There is much more to learn about apt, explore commands like add-apt-repository, apt-key and apropos apt.

the Red Hat package manager (rpm)

On Red Hat and other distros of that family, the Red Hat package manager (RPM) is used to install, upgrade and remove software. There's a basic command, rpm, and a more advanced tool, dnf (comparable with the situation on Debian-based systems, where dpkg is the basic tool and apt the more advanced one). When you install a graphical desktop, there's also a GUI tool for package management, but we won't be discussing that here.

Software distributed in the rpm format will have a file name following this format: package-version-release.architecture.rpm. For example, the package name openssh-server-8.7p1-34.el9.x86_64.rpm has the following components:

  • package name: openssh-server
  • version: 8.7p1
  • release: 34.el9 (el9 stands for Enterprise Linux 9, indicating it is compatible with RHEL 9)
  • architecture: x86_64 (suitable for a 64-bit Intel/AMD processor)

We will start with discussing the dnf command, since that one is most commonly used. After that, we'll show how to use the rpm command.

dnf

The name of the dnf command has a bit of a convoluted history. It stands for "Dandified Yum", and is a fork/improvement of the yum package manager command. Yum stands for Yellowdog Updater, Modified, and was originally developed for the now defunct Yellow Dog Linux distribution (for the IBM POWER7 processor). Red Hat started using it in RHEL 5 and it was the default package manager for Red Hat and its derivatives for many years. However, more recently, they developed dnf to replace yum with the former now being the default package manager for Fedora, Red Hat Enterprise Linux and its derivatives.

The dnf command works quite similarly to the apt command on Debian-based systems. It has similar subcommands, which we will discuss in the next sections. However, an equivalent for apt update does not exist. The dnf command will automatically update its package database whenever you execute it.

dnf list

Issue dnf list to see a list of all packages that DNF knows about.

[student@el ~]$ dnf list | wc -l
6751
[student@el ~]$ dnf list --all | wc -l
6751

Add the option --available or --installed to see only the packages that are available for installation or installed on the system.

[student@el ~]$ dnf list --available | wc -l
6392
[student@el ~]$ dnf list --installed | wc -l
353

Issue dnf list $package to get all versions (in different repositories) of one package.

[student@el ~]$ dnf list kernel
Last metadata expiration check: 0:12:15 ago on Sun 25 Feb 2024 07:16:59 PM UTC.
Installed Packages
kernel.x86_64              5.14.0-362.8.1.el9_3        @anaconda
kernel.x86_64              5.14.0-362.13.1.el9_3       @baseos  
Available Packages
kernel.x86_64              5.14.0-362.18.1.el9_3       baseos   

To search for a package containing a certain string in the description or name use dnf search $string.

[student@el ~]$ dnf search openssh
Last metadata expiration check: 0:15:35 ago on Sun 25 Feb 2024 07:16:59 PM UTC.
========================= Name Exactly Matched: openssh ========================
openssh.x86_64 : An open source implementation of SSH protocol version 2
======================== Name & Summary Matched: openssh =======================
openssh-askpass.x86_64 : A passphrase dialog for OpenSSH and X
openssh-keycat.x86_64 : A mls keycat backend for openssh
============================= Name Matched: openssh ============================
openssh-clients.x86_64 : An open source SSH client applications
openssh-server.x86_64 : An open source SSH server daemon
[student@el ~]$ dnf search epel
Last metadata expiration check: 0:18:51 ago on Sun 25 Feb 2024 07:16:59 PM UTC.
============================== Name Matched: epel ==============================
epel-release.noarch : Extra Packages for Enterprise Linux repository configuration

dnf info

Information about a specific package can be obtained with dnf info $package.

[student@el ~]$ dnf info epel-release
Last metadata expiration check: 1:15:53 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
Installed Packages
Name         : epel-release
Version      : 9
Release      : 7.el9
Architecture : noarch
Size         : 26 k
Source       : epel-release-9-7.el9.src.rpm
Repository   : @System
From repo    : epel
Summary      : Extra Packages for Enterprise Linux repository configuration     
URL          : http://download.fedoraproject.org/pub/epel
License      : GPLv2
Description  : This package contains the Extra Packages for Enterprise Linux    
             : (EPEL) repository GPG key as well as configuration for yum.      

This gives you a lot of information about the package, including the version, release, architecture, size, source, repository, summary, link to the project website, license and description.

If the repository is indicated as @System, it means that the package is installed. Otherwise, it would show the name of the repository from which the package would be installed.

[student@el ~]$ dnf info zork
Last metadata expiration check: 1:19:14 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
Available Packages
Name         : zork
Version      : 1.0.3
Release      : 5.el9
Architecture : x86_64
Size         : 179 k
Source       : zork-1.0.3-5.el9.src.rpm
Repository   : epel
Summary      : Public Domain original DUNGEON game (Zork I)
URL          : https://github.com/devshane/zork
License      : Public Domain
Description  : Public Domain source code to the original DUNGEON game (Zork I). 
[...]

dnf install

To install an application, use dnf install $package. Naturally, dnf will install all the necessary dependencies.

[student@el ~]$ sudo dnf install epel-release
Last metadata expiration check: 2:07:04 ago on Sun 25 Feb 2024 05:32:50 PM UTC.
Dependencies resolved.
================================================================================
 Package               Architecture    Version           Repository        Size 
================================================================================
Installing:
 epel-release          noarch          9-5.el9           extras            18 k 

Transaction Summary
================================================================================
Install  1 Package

Total download size: 18 k
Installed size: 25 k
Is this ok [y/N]: y
Downloading Packages:
epel-release-9-5.el9.noarch.rpm                       62 kB/s |  18 kB     00:00
--------------------------------------------------------------------------------
Total                                                 23 kB/s |  18 kB     00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                         1/1
  Installing       : epel-release-9-5.el9.noarch                             1/1
  Running scriptlet: epel-release-9-5.el9.noarch                             1/1
Many EPEL packages require the CodeReady Builder (CRB) repository.
It is recommended that you run /usr/bin/crb enable to enable the CRB repository.

  Verifying        : epel-release-9-5.el9.noarch                             1/1

Installed:
  epel-release-9-5.el9.noarch

Complete!

Add the option -y to skip confirmation. If the package is already installed, install will upgrade the package to the latest version.

[student@el ~]$ sudo dnf install -y sudo
Last metadata expiration check: 0:01:45 ago on Sun 25 Feb 2024 07:43:07 PM UTC.
Package sudo-1.9.5p2-9.el9.x86_64 is already installed.
Dependencies resolved.
================================================================================
 Package       Architecture    Version                    Repository       Size
================================================================================
Upgrading:
 sudo          x86_64          1.9.5p2-10.el9_3           baseos          1.0 M

Transaction Summary
================================================================================
Upgrade  1 Package

Total download size: 1.0 M
Downloading Packages:
sudo-1.9.5p2-10.el9_3.x86_64.rpm                3.0 MB/s | 1.0 MB     00:00    
--------------------------------------------------------------------------------
Total                                           1.3 MB/s | 1.0 MB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Upgrading        : sudo-1.9.5p2-10.el9_3.x86_64                           1/2 
  Running scriptlet: sudo-1.9.5p2-10.el9_3.x86_64                           1/2 
  Cleanup          : sudo-1.9.5p2-9.el9.x86_64                              2/2 
  Running scriptlet: sudo-1.9.5p2-9.el9.x86_64                              2/2 
  Verifying        : sudo-1.9.5p2-10.el9_3.x86_64                           1/2 
  Verifying        : sudo-1.9.5p2-9.el9.x86_64                              2/2 

Upgraded:
  sudo-1.9.5p2-10.el9_3.x86_64

Complete!

You can add more than one parameter here.

[student@el ~]$ sudo dnf install httpd mod_ssl mariadb-server php php-mysqlnd

dnf upgrade

To bring all applications up to date by downloading and installing them, issue dnf upgrade. All software that was installed via dnf will be updated to the latest version that is available in the repository.

[student@el ~]$ sudo dnf upgrade
Last metadata expiration check: 0:05:19 ago on Sun 25 Feb 2024 07:43:07 PM UTC.
Dependencies resolved.
================================================================================
 Package                  Arch    Version                      Repository  Size 
================================================================================
Installing:
 kernel                   x86_64  5.14.0-362.18.1.el9_3        baseos     9.4 k 
Upgrading:
 epel-release             noarch  9-7.el9                      epel        19 k 
 gnutls                   x86_64  3.7.6-23.el9_3.3             baseos     1.0 M 
[...]

Transaction Summary
================================================================================
Install  10 Packages
Upgrade  12 Packages

Total download size: 89 M
Is this ok [y/N]: y
Downloading Packages:
(1/22): graphite2-1.3.14-9.el9.x86_64.rpm       189 kB/s |  94 kB     00:00    
(2/22): freetype-2.10.4-9.el9.x86_64.rpm        752 kB/s | 387 kB     00:00     
[...]
Complete!

If you only want to update one package, use dnf upgrade $package. It behaves the same as dnf install $package.

dnf provides

To search for a package containing a certain file use dnf provides $filename (or globbing pattern). This is especially useful if you want to install a specific command that has a different name than the package name. For example, say that you've heard about the ag command that is a faster alternative to grep. The command dnf search ag spews out too much output, so no useful results:

[student@el ~]$ dnf search ag | wc -l
Last metadata expiration check: 0:02:48 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
2979

Listing available packages with ag shows that there is no such package:

[student@el ~]$ dnf list --available ag
Last metadata expiration check: 0:04:05 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
Error: No matching Packages to list
[student@el ~]$ dnf list --available ag*
Last metadata expiration check: 0:04:09 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
Available Packages
Agda.x86_64                    2.6.2.2-36.el9                               epel
Agda-common.noarch             2.6.2.2-36.el9                               epel
aggregate6.noarch              1.0.12-2.el9                                 epel
agrep.x86_64                   0.8.0-34.20140228gitc2f5d13.el9              epel

The last package looks promising, but it's not the one we're looking for. So let's use dnf provides to find out which package contains the ag command. If the command is ag, we expect that it is installed in one of the bin/ directories, i.e. /bin, /usr/bin, /sbin, /usr/sbin, /usr/local/bin, /usr/local/sbin, /usr/local/bin, /usr/local/sbin. We can summarize the possible path names with globbing pattern *bin/ag:

[student@el ~]$ dnf provides *bin/ag
Last metadata expiration check: 0:07:13 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
the_silver_searcher-2.2.0^2020704.5a1c8d8-3.el9.x86_64 : Super-fast text
                                                       : searching tool (ag)
Repo        : epel
Matched from:
Other       : *bin/ag
[student@el ~]$ sudo dnf install -y the_silver_searcher

So the name of the package is the_silver_searcher (ag being the chemical symbol for silver) and it is provided by the EPEL repository (Extra Packages for Enterprise Linux). We can install it with dnf install the_silver_searcher.

dnf remove

Removing a package is done with dnf remove $package. This will remove the package and all its dependencies that are not needed by other packages.

[student@el ~]$ sudo dnf remove net-tools
Dependencies resolved.
================================================================================
 Package        Arch        Version                        Repository      Size 
================================================================================
Removing:
 net-tools      x86_64      2.0-0.62.20160912git.el9       @anaconda      912 k 

Transaction Summary
================================================================================
Remove  1 Package

Freed space: 912 k
Is this ok [y/N]: y
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Erasing          : net-tools-2.0-0.62.20160912git.el9.x86_64              1/1 
  Verifying        : net-tools-2.0-0.62.20160912git.el9.x86_64              1/1 

Removed:
  net-tools-2.0-0.62.20160912git.el9.x86_64

Complete!

By the way, this package, net-tools, contains commands that are considered to be obsolete and have been replaced by other, newer implementations. You don't really need it, so it's a good example for this section. If you removed it, feel free to reinstall it if you want!

dnf software groups

Issue dnf grouplist to see a list of all available software groups.

[student@el ~]$ dnf grouplist
Last metadata expiration check: 1:00:37 ago on Sun 25 Feb 2024 07:55:24 PM UTC.
Available Environment Groups:
   Server with GUI
   Server
   Minimal Install
   Workstation
   KDE Plasma Workspaces
   Virtualization Host
   Custom Operating System
Available Groups:
   RPM Development Tools
   .NET Development
   Container Management
   Console Internet Tools
   Graphical Administration Tools
   Scientific Support
   Headless Management
   Smart Card Support
   Legacy UNIX Compatibility
   Security Tools
   Network Servers
   System Tools
   Development Tools
   Fedora Packager
   VideoLAN Client
   Xfce

To install a set of applications, brought together via a group, use yum groupinstall $groupname.

[student@el ~]$ sudo dnf groupinstall 'Security Tools'
Last metadata expiration check: 1:00:35 ago on Sun 25 Feb 2024 08:03:34 PM UTC.
Dependencies resolved.
================================================================================
 Package                Arch      Version                    Repository    Size 
================================================================================
Installing group/module packages:
 scap-security-guide    noarch    0.1.69-3.el9_3.alma.1      appstream    813 k 
Installing dependencies:
 libtool-ltdl           x86_64    2.4.6-45.el9               appstream     36 k 
 libxslt                x86_64    1.1.34-9.el9               appstream    240 k 
 openscap               x86_64    1:1.3.8-1.el9_2.alma.2     appstream    1.9 M 
 openscap-scanner       x86_64    1:1.3.8-1.el9_2.alma.2     appstream     57 k 
 xml-common             noarch    0.6.3-58.el9               appstream     31 k 
 xmlsec1                x86_64    1.2.29-9.el9               appstream    189 k 
 xmlsec1-openssl        x86_64    1.2.29-9.el9               appstream     90 k 
Installing Groups:
 Security Tools

Transaction Summary
================================================================================
Install  8 Packages

Total download size: 3.3 M
Installed size: 103 M
Is this ok [y/N]: 
[...]

Read the manual page of dnf for more information about managing groups in dnf. In practice, chances are that you won't need this feature very often.

rpm -qa

In the following sections, we'll show what you can do with the rpm command.

To obtain a list of all installed software, use the rpm -qa command.

[student@el ~]$ rpm -qa | grep ssh
libssh-config-0.10.4-11.el9.noarch
libssh-0.10.4-11.el9.x86_64
openssh-8.7p1-34.el9.x86_64
openssh-clients-8.7p1-34.el9.x86_64
openssh-server-8.7p1-34.el9.x86_64

rpm -q

To verify whether one package is installed, use rpm -q.

[student@el ~]$ rpm -q vim-enhanced
package vim-enhanced is not installed
[student@el ~]$ rpm -q vim-minimal
vim-minimal-8.2.2637-20.el9_1.x86_64
[student@el ~]$ rpm -q kernel
kernel-5.14.0-362.8.1.el9_3.x86_64
kernel-5.14.0-362.13.1.el9_3.x86_64
kernel-5.14.0-362.18.1.el9_3.x86_64

rpm -ql

To see which files are installed by a package, use rpm -ql.

[student@el ~]$ rpm -ql vim-minimal
/etc/virc
/usr/bin/ex
/usr/bin/rvi
/usr/bin/rview
/usr/bin/vi
/usr/bin/view
/usr/lib/.build-id
/usr/lib/.build-id/c6
/usr/lib/.build-id/c6/aa3d8d79f09dd48e99475c332bed4df39d76e1
/usr/libexec/vi
/usr/share/man/man1/ex.1.gz
/usr/share/man/man1/rvi.1.gz
/usr/share/man/man1/rview.1.gz
/usr/share/man/man1/vi.1.gz
/usr/share/man/man1/view.1.gz
/usr/share/man/man5/virc.5.gz

rpm -Uvh

To install or upgrade a package, use the -Uvh switches. The -U switch is the same as -i for install, except that older versions of the software are removed. The -vh switches are for nicer output.

You would typically use this command to install an .rpm package that you have downloaded from the internet. Beware, though, that rpm does not resolve dependencies, so you might need to install other packages first.

[student@el ~]$ sudo rpm -Uvh ./htop-3.3.0-1.el9.x86_64.rpm 
error: Failed dependencies:
        libhwloc.so.15()(64bit) is needed by htop-3.3.0-1.el9.x86_64

rpm -e

To remove a package, use the -e switch.

[student@el ~]$ rpm -q net-tools
net-tools-2.0-0.62.20160912git.el9.x86_64
[student@el ~]$ sudo rpm -e net-tools
[student@el ~]$ rpm -q net-tools
package net-tools is not installed

rpm -e verifies dependencies, and thus will prevent you from accidentailly erasing packages that are needed by other packages.

[student@el ~]$ sudo rpm -e slang
error: Failed dependencies:
        libslang.so.2()(64bit) is needed by (installed) newt-0.52.21-11.el9.x86_64
        libslang.so.2(SLANG2)(64bit) is needed by (installed) newt-0.52.21-11.el9.x86_64

Package cache

When dnf installs or upgrades a package, it will download the package from the repository and store it temporarily in the cache. The cache also contains repository metadata. The default location of the cache is /var/cache/dnf. You can clean the cache with dnf clean all.

[student@el ~]$ dnf clean all 
51 files removed

Remark that .rpm files will normally be removed automatically after they were installed successfully. You can change this behavior in /etc/dnf/dnf.conf by setting keepcache=1.

Configuration

The main configuration file for dnf is /etc/dnf/dnf.conf. This file contains a few basic settings. The location of package repositories that are available to the system are kept in the directory /etc/yum.repos.d/. Each repository has its own file, with a .repo extension.

[student@el ~]$ ls /etc/yum.repos.d/
almalinux-appstream.repo         almalinux-resilientstorage.repo
almalinux-baseos.repo            almalinux-rt.repo
almalinux-crb.repo               almalinux-saphana.repo
almalinux-extras.repo            almalinux-sap.repo
almalinux-highavailability.repo  epel-cisco-openh264.repo
almalinux-nfv.repo               epel.repo
almalinux-plus.repo              epel-testing.repo

A repo file is a text file in the INI format, and contains information about the repository, such as the name, the base URL, the GPG key, etc. Here's an example with part of the contents of the epel.repo file:

[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
## It is much more secure to use the metalink, but if you wish to use a local mirror
## place its address here.
#baseurl=https://download.example/pub/epel/$releasever/Everything/$basearch/    
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir
enabled=1
gpgcheck=1
countme=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$releasever

Working with multiple repositories

You can get a list of the currently enabled repositories with dnf repolist.

[student@el ~]$ dnf repolist
repo id             repo name
appstream           AlmaLinux 9 - AppStream
baseos              AlmaLinux 9 - BaseOS
epel                Extra Packages for Enterprise Linux 9 - x86_64
epel-cisco-openh264 Extra Packages for Enterprise Linux 9 openh264 (From Cisco) - x86_64
extras              AlmaLinux 9 - Extras

And specific information about a repository with dnf repoinfo $repo.

[student@el ~]$ dnf repoinfo epel-testing
Last metadata expiration check: 0:02:40 ago on Sun 25 Feb 2024 10:32:04 PM UTC.
Repo-id            : epel-testing
Repo-name          : Extra Packages for Enterprise Linux 9 - Testing - x86_64   
Repo-status        : disabled
Repo-metalink      : https://mirrors.fedoraproject.org/metalink?repo=testing-epel9&arch=x86_64&infra=$infra&content=$contentdir
Repo-expire        : 172,800 second(s) (last: unknown)
Repo-filename      : /etc/yum.repos.d/epel-testing.repo
Total packages: 0

One important flag for dnf is --enablerepo. Use this command if you want to use a repository that is not enabled by default. For example, let's say you want to install the latest version of fail2ban, but the one in the "normal" repository is too old:

[student@el ~]$ dnf list --available fail2ban
Last metadata expiration check: 0:01:44 ago on Sun 25 Feb 2024 10:32:04 PM UTC.
Available Packages
fail2ban.noarch                         1.0.2-7.el9                         epel

Maybe epel-testing has a newer version:

[student@el ~]$ dnf list --available --repo epel-testing fail2ban
Last metadata expiration check: 0:06:10 ago on Sun 25 Feb 2024 10:30:33 PM UTC.
Available Packages
fail2ban.noarch                    1.0.2-12.el9                     epel-testing

It does, but you won't be able to install it due to the fact that epel-testing is disabled. However, you can temporarily enable it with the --enablerepo flag:

[student@el ~]$ sudo dnf install --enablerepo=epel-testing fail2ban
[sudo] password for student: 
Last metadata expiration check: 0:13:34 ago on Sun 25 Feb 2024 10:24:12 PM UTC.
Dependencies resolved.
================================================================================
 Package                 Arch        Version            Repository         Size
================================================================================
Installing:
 fail2ban                noarch      1.0.2-12.el9       epel-testing      8.8 k 
Installing dependencies:
 esmtp                   x86_64      1.2-19.el9         epel               52 k 
 fail2ban-firewalld      noarch      1.0.2-12.el9       epel-testing      8.9 k 
 fail2ban-selinux        noarch      1.0.2-12.el9       epel-testing       29 k 
 fail2ban-sendmail       noarch      1.0.2-12.el9       epel-testing       12 k 
 fail2ban-server         noarch      1.0.2-12.el9       epel-testing      444 k 
 libesmtp                x86_64      1.0.6-24.el9       epel               66 k 
 liblockfile             x86_64      1.14-10.el9        baseos             28 k 

Transaction Summary
================================================================================
Install  8 Packages

Total download size: 647 k
Installed size: 1.8 M
Is this ok [y/N]:

pip, the Python package manager

Some programming languages, a.o. Python, have their own package management system that allows you to install applications and/or libraries. In the case of Python, the package manager is called pip. It is used to install Python packages from the Python Package Index (PyPI). In fact, there are multiple package managers for Python (a.o. easy_install, conda, etc.), but pip is the most widely used.

As a system administrator, or as an end user, this sometimes puts you in a difficult position. Some widely known and used Python libraries can be installed both through your distribution's package manager, and through pip. Which one to choose is not always clear. In general, it is best to use the distribution's package manager, as it will integrate the package into the system and will be updated when the system is updated. However, some packages are not available in the distribution's repositories, or the version you get with pip is more recent. In that case, you can use pip to install the package.

Another thing to note is that pip can be used as a normal user, or as root, and in each case it will install the package in a different location. When you install a package as a normal user, it will be installed in your home directory, and will only be available to you. When you install a package as root, it will be installed system-wide, and will be available to all users. However, if you install a package as root, you will get a warning message:

WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

A virtual environment is a way to create an isolated environment for a Python project, where you can install packages without affecting the system's Python installation. This is especially useful when you are developing Python applications, and you want to make sure that the libraries you use are the same as the ones used in production. Using and managing virtual environments is beyond the scope of this course, but you can find more information in the Python documentation.

As general guidelines, we suggest the following:

  • If the library or application is available in the distribution's repositories, use the distribution's package manager to install it.
  • Avoid installing Python libraries or applications system-wide as root using pip.
  • Normal users may use pip to install Python libraries or applications in their home directory.

installing pip

pip may not be installed by default on your system. You can install it using your distribution's package manager. For example, on Debian-based systems, you can install it using apt:

student@debian:~$ sudo apt install python3-pip

On Red Hat-based systems, you can install it using dnf:

student@el ~$ sudo dnf install python3-pip

listing packages

You can list the packages installed with pip using the list command:

student@linux:~$ pip list
Package         Version
--------------- --------
dbus-python     1.2.18
distro          1.5.0
gpg             1.15.1
libcomps        0.1.18
nftables        0.1
pip             21.2.3
PyGObject       3.40.1
python-dateutil 2.8.1
PyYAML          5.4.1
rpm             4.16.1.3
selinux         3.5
sepolicy        3.5
setools         4.4.3
setuptools      53.0.0
six             1.15.0
systemd-python  234

searching for packages

Searching for packages can NOT be done on the command line. To search for packages, you can use the Python Package Index website instead. If you try pip search, you will get an error message:

student@linux:~$ pip search ansible
ERROR: XMLRPC request failed [code: -32500]
RuntimeError: PyPI no longer supports 'pip search' (or XML-RPC search). Please use https://pypi.org/search (via a browser) instead. See https://warehouse.pypa.io/api-reference/xml-rpc.html#deprecated-methods for more information.

installing packages

You can install a package using the install command:

student@linux:~$ pip install ansible

Just like apt and dnf, pip will install the package and its dependencies.

removing packages

Uninstalling a package is done with the uninstall command:

student@linux:~$ pip uninstall ansible

Unfortunately, dependencies are not removed when you uninstall a package with pip.

container-based package managers

With the release of Docker, container-based virtualization has become very popular as a method of distributing and deploying applications on servers. One of the advantages of containers is that they offer a sandbox environment for applications, meaning the application and its dependencies are isolated from the rest of the system. This makes it possible to run applications with different dependencies on the same server, without the risk of conflicts. Containers are also very lightweight, they don't impose much overhead on the host system.

Now, there is no reason why containers can't be used to deploy applications on desktop systems as well. In fact, there are several container-based package managers that allow you to install and run applications in containers on your desktop. The advantage is that third party software vendors can distribute their applications independent of the Linux distribution, so they don't need to maintain different packages for (each family of) distribution(s). The disadvantage is that each application comes with their own dependencies, so you lose the advantage of sharing libraries between applications. Also, since the application is running in a container, it may not integrate well with the rest of the system, or may have only limited permissions to access files or other resources on your computer.

As with many Linux-based technologies, there are multiple tools to choose from. The most popular ones are Flatpak and Snap.

flatpak

Flatpak is a container-based package manager developed by an independent community of contributors, volunteers and supporting organizations. It is available for most Linux distributions and is supported by a large number of third party software vendors. Red Hat was one of the first to endorse Flatpak, and many others followed. Fedora Silverblue is a variant of Fedora that uses Flatpak as its primary package manager. Linux Mint also has Flatpak support enabled by default: in the Software Manager, some applications like Bitwarden, Slack, VS Code, etc. are available as Flatpaks.

If you want to use a container based package manager, Flatpak is probably the best choice for any Linux distribution other than Ubuntu.

In the following example, we'll install the open source password manager Bitwarden with Flatpak on a Linux Mint system. Remark that you don't need to be root to install Flatpak applications!

student@mint:~$ flatpak search Bitwarden
Name       Description                            Application ID         Version  Branch Remotes
Bitwarden  A secure and free password manager for com.bitwarden.desktop  2024.2.0 stable flathub
Goldwarden A Bitwarden compatible desktop client  com.quexten.Goldwarden 0.2.13   stable flathub
student@mint:~$ flatpak install Bitwarden
Looking for matches…
Found ref ‘app/com.bitwarden.desktop/x86_64/stable’ in remote ‘flathub’ (system).
Use this ref? [Y/n]: y
Required runtime for com.bitwarden.desktop/x86_64/stable (runtime/org.freedesktop.Platform/x86_64/23.08) found in remote flathub
Do you want to install it? [Y/n]: y

com.bitwarden.desktop permissions:
    ipc                    network                      wayland       x11       dri       file access [1]
    dbus access [2]        system dbus access [3]

    [1] xdg-download
    [2] com.canonical.AppMenu.Registrar, org.freedesktop.Notifications, org.freedesktop.secrets, org.kde.StatusNotifierWatcher
    [3] org.freedesktop.login1


        ID                                   Branch      Op Remote  Download
 1. [✓] com.bitwarden.desktop.Locale         stable      i  flathub 300.7 kB / 9.8 MB
 2. [✓] org.freedesktop.Platform.GL.default  23.08       i  flathub 162.0 MB / 162.3 MB
 3. [✓] org.freedesktop.Platform.GL.default  23.08-extra i  flathub  17.9 MB / 162.3 MB
 4. [✓] org.freedesktop.Platform.Locale      23.08       i  flathub  17.9 kB / 359.9 MB
 5. [✓] org.freedesktop.Platform             23.08       i  flathub 171.6 MB / 225.6 MB
 6. [✓] com.bitwarden.desktop                stable      i  flathub 132.5 MB / 133.4 MB

Installation complete.

To remove a Flatpak application, you can use the uninstall command:

student@mint:~$ flatpak uninstall Bitwarden
Found installed ref ‘app/com.bitwarden.desktop/x86_64/stable’ (system). Is this correct? [Y/n]: y


        ID                                   Branch         Op
 1. [-] com.bitwarden.desktop                stable         r
 2. [-] com.bitwarden.desktop.Locale         stable         r

Uninstall complete.

snap

Snap was developed by Canonical and is installed by default on Ubuntu. It is also available for other distributions (like the official Ubuntu derivatives, Solus and Zorin OS), but it is not as widely supported as Flatpak. Snap was also designed to work for cloud applications and Internet of Things devices.

In the following example, we'll install Grafana on an Ubuntu Server system.

student@ubuntu:~$ snap search grafana
Name          Version Publisher  Notes Summary
grafana       6.7.4   canonical✓ -     feature rich metrics dashboard and graph editor        
grafana-agent 0.35.4  0x12b      -     Telemetry Agent
[...]
student@ubuntu:~$ sudo snap install grafana
grafana 6.7.4 from Canonical✓ installed

To uninstall a Snap application, you can use the remove command:

student@ubuntu:~$ sudo snap remove grafana
grafana removed

downloading software outside the repository

These days, the case where you need software that is not available as a binary package has become exceedingly rare. However, if you want to install some experimental tool that hasn't been packaged yet, or you want to test the very latest experimental version of an application, you may have to download the source code and compile it yourself. Usually, the source code is available on the project's website or on a code hosting platform like GitHub, GitLab or Bitbucket. You then either download the source code as a tgz, .tar.gz, .tar.bz2, tar.xz file (also called a tarball) or you can clone the repository using git.

In the example below, we assume that you have downloaded the source code of an application written in C or C++, as is common for many Linux applications. Remark that in order to be able to compile the source code, you need to have the C compiler gcc and the build tool make installed on your system. You can install these using your distribution's package manager. Also, many applications depend on other libraries, which also have to be installed as source.

example: compiling zork

As an example, we will download the source code for Zork, an ancient text based adventure game, and compile it on a Fedora system. The source code is available on GitHub. We have installed git, gcc and make beforehand.

[student@fedora ~]$ git clone https://github.com/devshane/zork.git
Cloning into 'zork'...
remote: Enumerating objects: 79, done.
remote: Total 79 (delta 0), reused 0 (delta 0), pack-reused 79
Receiving objects: 100% (79/79), 241.70 KiB | 2.14 MiB/s, done.
Resolving deltas: 100% (20/20), done.
[student@fedora ~]$ cd zork/
[student@fedora zork]$ ls
actors.c  demons.c  dmain.c  dso3.c  dso6.c  dtextc.dat  dverb2.c  history   Makefile  np2.c  nrooms.c  README.md   sobjs.c   vars.h
ballop.c  dgame.c   dso1.c   dso4.c  dso7.c  dungeon.6   funcs.h   lightp.c  nobjs.c   np3.c  objcts.c  readme.txt  supp.c    verbs.c
clockr.c  dinit.c   dso2.c   dso5.c  dsub.c  dverb1.c    gdt.c     local.c   np1.c     np.c   parse.h   rooms.c     sverbs.c  villns.c
[student@fedora ~]$ make
cc -g    -c -o actors.o actors.c
cc -g    -c -o ballop.o ballop.c
cc -g    -c -o clockr.o clockr.c
[...etc...]
cc -g  -o zork actors.o ballop.o clockr.o demons.o dgame.o dinit.o dmain.o dso1.o dso2.o dso3.o dso4.o dso5.o dso6.o dso7.o dsub.o dverb1.o dverb2.o gdt.o lightp.o local.o nobjs.o np.o np1.o np2.o np3.o nrooms.o objcts.o rooms.o sobjs.o supp.o sverbs.o verbs.o villns.o -ltermcap
/usr/bin/ld: cannot find -ltermcap: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [Makefile:69: dungeon] Error 1

As you can see, the make command fails because it cannot find the termcap library. This is a library that is used to control the terminal, and it is not installed on our system. This is a common problem when you try to install packages from source. You need to install these dependencies yourself and these are not always easy to find. In this case, we can install the ncurses-devel library, which is a modern replacement for termcap. How did we now that? We used dnf provides to find library files that contain the string termcap (remark that the command took a long time to finish):

[student@fedora zork]$ dnf provides '*libtermcap.so*'
Last metadata expiration check: 1:56:05 ago on Mon 26 Feb 2024 05:46:43 PM UTC.
ncurses-devel-6.4-7.20230520.fc39.i686 : Development files for the ncurses library
Repo        : fedora
Matched from:
Other       : *libtermcap.so*
[student@fedora ~]$ sudo dnf install ncurses-devel
[...etc...]

Let's try to compile again:

[student@fedora zork]$ make
cc -g    -c -o actors.o actors.c
cc -g    -c -o ballop.o ballop.c
[...etc...]
cc -g    -c -o villns.o villns.c
cc -g  -o zork actors.o ballop.o clockr.o demons.o dgame.o dinit.o dmain.o dso1.o dso2.o dso3.o dso4.o dso5.o dso6.o dso7.o dsub.o dverb1.o dverb2.o gdt.o lightp.o local.o nobjs.o np.o np1.o np2.o np3.o nrooms.o objcts.o rooms.o sobjs.o supp.o sverbs.o verbs.o villns.o -ltermcap
[student@fedora zork]$

The command seems to have succeeded. The current directory now contains a new file called zork. This is the compiled application and it has execute permissions. You can run it by typing ./zork:

[student@fedora zork]$ ls -l zork
-rwxr-xr-x. 1 vagrant vagrant 400968 Feb 26 19:45 zork
[student@fedora zork]$ file zork
zork: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3089e3cb1c1a7fc1cc1db41c3aa578c0b52f83f3, for GNU/Linux 3.2.0, with debug_info, not stripped
[student@fedora zork]$ ./zork
Welcome to Dungeon.                     This version created 11-MAR-91.
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
>

In this case, installing the game is as simple as copying the zork file to a directory in your PATH, like /usr/local/bin or (for a computer game) /usr/local/games. However, most Makefiles provide a way to install the application in the system, usually by running make install. This will copy the executable, manual pages and other documentation to the correct location.

[student@fedora zork]$ sudo make install
mkdir -p /usr/games  /usr/share/man/man6
cp zork /usr/games
cp dtextc.dat /usr/games/lib
cp dungeon.6 /usr/share/man/man6/

Remark that the "official" location where manually installed applications belong in a Linux directory structure is /usr/local (for applications that follow the Filesystem Hierarchy Standard) or /opt (for applications that want to keep all files in a single directory).

installing from a tarball

Before unpacking a tarball, it's useful to check its contents:

student@linux:~$ tar tf $downloadedFile.tgz

The t option lists the content of the archive, f should be followed by the filename of the tarball. For .tgz, you may add option z and for .tar.bz2 option j. However, the tar command should recognize the compression method automatically.

Check whether the package archive unpacks in a subdirectory (which is the preferred case) or in the current directory and create a subdirectory yourself if necessary. After that, you can unpack the tarball:

student@linux:~$ tar xf $downloadedFile.tgz

Now, be sure to read the README file carefully! Normally the readme will explain what to do after download.

Usually the steps are always the same three:

  1. running a script ./configure. It will gather information about your system that is needed to compile the software so that it can actually run on your system
  2. executing the command make (which is the actual compiling)
  3. finally, executing make install to copy the files to their proper location.

practice: package management

  1. Verify whether gcc, sudo and zork are installed.

  2. Use dnf or apt to search for and install the scp, tmux, and man-pages packages. Did you find them all?

  3. Search the internet for \'webmin\' and figure out how to install it.

  4. If time permits, search for and install samba including the samba docs pdf files (thousands of pages in two pdf\'s).

solution: package management

  1. Verify whether gcc, sudo and zork are installed.

    On Enterprise Linux:

    rpm -qa | grep gcc
    rpm -qa | grep sudo
    rpm -qa | grep zork
    

    On Debian/Ubuntu:

    dpkg -l | grep gcc
    dpkg -l | grep sudo
    dpkg -l | grep zork
    
  2. Use dnf or apt to search for and install the scp, tmux, and man-pages packages. Did you find them all ?

    On Red Hat/CentOS:

    dnf search scp
    dnf search tmux
    dnf search man-pages
    

    On Debian/Ubuntu:

    apt search scp
    apt search tmux
    apt search man-pages
    
  3. Search the internet for 'webmin' and figure out how to install it.

    Google should point you to webmin.com. The download page helps you to download a repository file so you can install webmin with your package manager. The latest Webmin distribution is available in various package formats for download, a.o. .rpm, .deb, etc.

  4. If time permits, search for and install samba including the samba docs pdf files (thousands of pages in two pdf\'s).