RPM Package Versions

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 reverses the string, then cuts out the first two fields (version and 'release.os.arch'). Then it reverses the string again to get everything back as it should be.


Quelle: https://www.shellscript.sh/tips/rpm-versions/