Buy this tutorial as a PDF for only $5
14 May 2015
RPM Package Versions
A nice technique to split out an RPM package version, such as "1.12.14" into an array. Adapted from a Red Hat Satellite katello-ca-consumer package. This makes it easier to query the version, since "1.12.14" is not a real number and doesn't lend itself to comparison tests.
$ PACKAGE=subscription-manager $ rpm -q --queryformat='%{VERSION}' $PACKAGE 1.12.14 $ PACKAGE_VERSION="`rpm -q --queryformat='%{VERSION}' $PACKAGE | tr . ' '`" $ echo $PACKAGE_VERSION 1 12 14 $ declare -a PACKAGE_VERSION_ARRAY=($PACKAGE_VERSION) $ echo ${PACKAGE_VERSION_ARRAY[0]} 1 $ echo ${PACKAGE_VERSION_ARRAY[1]} 12 $ echo ${PACKAGE_VERSION_ARRAY[2]} 14 $
This can be useful as the basis of a tool to compare installed RPM packages between systems, for example. It also avoids the other problem with RPM package names. To take two packages at random:
- tsdb-1.27.29-1.el6.noarch.rpm
- yum-rhn-plugin-2.2.7-1.el6.noarch.rpm
It is clear that the hyphen (‐
) separates the package-name from the version and release number. But because yum-rhn-plugin also contains hyphens, it is not easy to split out the package name from the version. This rpm -q --queryformat
approach is guaranteed to get the version number.
Package Name
There is a second, somewhat-related problem associated with working out the package name. Because a name like "yum-rhn-plugin-2.2.7-1.el6.noarch.rpm
" as mentioned above, contains multiple hyphens in the actual package name (yum-rhn-plugin
), it is not possible to use a simple "cut
" to extract the package name. Consider these packages:
- net-tools-2.0-0.17.20131004git.el7.x86_64
- pinentry-0.8.1-14.el7.x86_64
- yum-cron-3.4.3-132.el7.centos.0.1.noarch
- libselinux-utils-2.2.2-6.el7.x86_64
- libmpc-1.0.1-3.el7.x86_64
Although these do follow a logical pattern which is easy enough for a person to understand, it is not so obvious how to code it. You can't use "cut
" alone, because although ostensibly the delimiter is the hypen (-
), that is also a valid character in the package name itself.
One solution is to use "cut
" along with the less well-known "rev
" utility (from util-linux
). This approach makes use of the fact that the total number of fields is fixed, and that the name comes at the beginning:
#!/bin/sh for fullname in `cat /tmp/rpmlist.txt` do echo -n "The package name in \"$fullname\" is: " echo $fullname | rev | cut -d'-' -f3- | rev done
The package name in "net-tools-2.0-0.17.20131004git.el7.x86_64" is: net-tools The package name in "pinentry-0.8.1-14.el7.x86_64" is: pinentry The package name in "yum-cron-3.4.3-132.el7.centos.0.1.noarch" is: yum-cron The package name in "libselinux-utils-2.2.2-6.el7.x86_64" is: libselinux-utils The package name in "libmpc-1.0.1-3.el7.x86_64" is: libmpc $
This rev
erses the string, then cut
s out the first two fields (version and 'release.os.arch'). Then it rev
erses the string again to get everything back as it should be.
Appreciate this site? Please consider making a donation:
Books and eBooks
My Shell Scripting books, available in Paperback and eBook formats.
![]() Shell Scripting Tutorial is this tutorial, in 88-page Paperback and eBook formats. Convenient to read on the go, and to keep by your desk as an ever-present companion. | ![]() Shell Scripting: Expert Recipes for Linux, Bash and more is my 564-page book on Shell Scripting. The first half explains the features of the shell; the second half has real-world shell scripts, organised by topic, with detailed discussion of each script. |
Contact
You can mail me with this form. If you expect a reply, please ensure that the address you specify is valid. Don't forget to include the simple addition question at the end of the form, to prove that you are a real person!