Fedora Package Management

See also Debian Package Management.

I started using Linux in 1996 using the Slackware distribution. A couple years later, I moved to the Red Hat distro because the promise of managed packages (with rpm, the Red Hat Package Manager) sounded great - Slackware's package management was simply unpacking tarballs. By the time Red Hat split its distro into the community driven Fedora and the commercial Red Hat, I was ready to leave again. A significant portion of that decision was driven by my growing dislike of rpm, which was notorious for "package dependency hell." By then I was more familiar with Linux system administration, so I moved to the somewhat less user-friendly Debian - which also happened to possess what was at the time the very best package management system, APT. When you said apt-get install package-x, if 'package-x' existed, apt-get would not only download and install it but all required dependencies in one shot.

A few months ago stability problems on both my primary laptop and my main computer inspired me to install Fedora on both (replacing Ubuntu ... for the purposes of this discussion, the same thing as Debian because Ubuntu also uses APT). So I found myself back in the land of rpm, yum, and dnf. rpm's notoriety for its inability to resolve package dependencies led to the creation of yum, the "Yellowdog Updater, Modified" (Yellowdog apparently still exists with a somewhat different purpose, but was at the time a Linux distro for Macintosh PowerPC-based computers). I never liked yum - it insisted on pulling updated package lists from remote sources Every. Single. Time. it was run, and was staggeringly slow about it. When I installed Fedora this time, I found we've moved on to dnf (apparently, somehow, that stands for "Dandified Yum" - and yes, I see that all the letters are there). dnf is, in my limited experience, faster and better behaved. Both dnf and yum use rpm in the background for package handling.

But, like all package managers, there are sometimes things dnf can't tell me easily. So I write scripts. I thought about using dnf to supply the information, but if dnf's data cache is more than an hour old (? not sure of the time-out), it will do an update and suddenly the command below takes 90 seconds instead of 0.5 seconds. And since we're only looking for already existing local information, the update isn't needed. If I want to know if a package with a certain name is installed but I can't remember the exact name:

# This is a bash function: put it in ~/.bashrc or /etc/basrc if you want it system-wide
rpmg ()
    rpm --queryformat="%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\t%{SIZE}b\n" -qa | grep --color=auto -i "$@"

To run it:

$ rpmg bash
bash-completion-2.5-1.fc25.noarch       904319b
bash-4.3.43-4.fc25.x86_64       6373104b

Okay, the output formatting isn't great, but the information is pretty nice.

Another thing I wanted to know is "what are the biggest packages on my system?"

rpmsz ()
    rpm --queryformat="%{SIZE}\t%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" -qa | sort -n

With hard drives being the size they are these days, this is less of an issue - but this can still be useful on old, low-end machines or a Raspberry Pi. The tail end of the output looks something like this:

55134286        kernel-core-4.9.6-200.fc25.x86_64
55137742        kernel-core-4.9.8-201.fc25.x86_64
64702367        graphviz-2.38.0-39.fc25.x86_64
66386178        gimp-2.8.20-1.fc25.x86_64
84746554        mariadb-server-10.1.21-1.fc25.x86_64
107744198       qt5-qtwebengine-5.7.1-4.fc25.x86_64
112832256       glibc-all-langpacks-2.24-4.fc25.x86_64
119508101       linux-firmware-20161205-69.git91ddce49.fc25.noarch
122305769       thunderbird-45.7.0-1.fc25.x86_64
143318616       firefox-51.0.1-2.fc25.x86_64
179010327       google-chrome-stable-56.0.2924.87-1.x86_64

This is typical: Kernels are always near the top (well, bottom in this case) of the list, and may or may not be beaten out by your browsers. If you have Java installed, it'll be right in the mix too.

Another question I find I ask a lot is "what package provides binary-x?" This turns out to be two very different questions, because it's fairly easy to answer if the binary is already installed:

$ rpm -qf $(which cal)

The command which cal translates itself in place to /usr/bin/cal, so that's the input that rpm -qf receives.

But this is a different question if the binary isn't yet installed:

$ tcsh
bash: tcsh: command not found
$ dnf provides \*/bin/tcsh
Last metadata expiration check: 13 days, 12:19:00 ago on Tue Jan 31 20:02:02 2017.
tcsh-6.19.00-14.fc25.x86_64 : An enhanced version of csh, the C shell
Repo        : fedora
$ dnf provides \*/bin/ncal
Last metadata expiration check: 13 days, 12:56:06 ago on Tue Jan 31 20:02:02 2017.
Error: No Matches found

(I was using ncal on a Mac - it turns out to be a FreeBSD thing, not readily available on Linux.) The ugly syntax \*/bin/tcsh is necessitated because dnf wants a full path - you can't just say tcsh or you'll get "No Matches found."