4

I need to write a script to verify that an RPM is at least a given version in Linux.

  • QUESTION 1: How can I get the RPM version in a variable $RPM_VERSION, so that it contains the version all the way to ".src.rpm"?
  • QUESTION 2: What is the best approach to compare the 2 versions?

For example: rpm-4.2-9.69.src.rpm compared to rpm-4.14-0.69.src.rpm. This is my attempt, but it doesn't work:

STR_BASE_ACCEPTABLE_VER="rpm-4.2-0.69.src.rpm"

if  [[ "$RPM_VERSION" < "$STR_BASE_ACCEPTABLE_VER" ]]; then   
    echo "$RPM_VERSION is too low..."  \
else   
    echo "$RPM_VERSION is fine"  \
fi
5

Parsing versions

Hackey way

For the first part, I'd query RPM for the particular version info like so.

$ rpm -qi vim-enhanced | grep Version
Version     : 7.4.417

You can then parse this out like so:

$ rpm -qi vim-enhanced | awk -F': ' '/Version/ {print $2}'
7.4.417

This can be captured into a variable like so:

$ RPM_VERSION=$(rpm -qi vim-enhanced | awk -F': ' '/Version/ {print $2}')

$ echo $RPM_VERSION
7.4.417

Using queryformats

The rpm tool also provides a facility called --queryformat which allows you to customize the output that it generates. Knowing this you can tell rpm to print the "VERSION" macro like so:

$ rpm -q --queryformat '%{VERSION}' vim-enhanced
7.4.417

Putting it to a variable:

$ RPM_VERSION=$(rpm -q --queryformat '%{VERSION}' vim-enhanced)

NOTE: You can see all the query tags using the --querytags switch to rpm, for example:

$ rpm --querytags | head -5
ARCH
ARCHIVESIZE
BASENAMES
BUGURL
BUILDARCHS

Comparing versions

To do the comparing is going to be trickier. Luckily there's a tool in the rpmdevtools package called rpmdev-vercmp that can assist you greatly.

Usage

$ rpmdev-vercmp --help

rpmdev-vercmp <epoch1> <ver1> <release1> <epoch2> <ver2> <release2>
rpmdev-vercmp <EVR1> <EVR2>
rpmdev-vercmp # with no arguments, prompt

Exit status is 0 if the EVR's are equal, 11 if EVR1 is newer, and 12 if EVR2
is newer.  Other exit statuses indicate problems.

If you notice the exit statuses that it returns, you can find out which version is newer simply by asking this tool, giving it the 2 names of the RPM's.

Example

$ rpmdev-vercmp rpm-4.2-9.69 rpm-4.14-0.69
rpm-4.2-9.69 < rpm-4.14-0.69
$ echo $?
12

So based on the exit code of 12, the 2nd argument would be the newer of the 2.

Putting it together

Your solution would then look something like this:

rpmdev-vercmp $RPM_VERSION $STR_BASE_ACCEPTABLE_VER > /dev/null
if [[ $? == 12 ]]; then
  echo "$RPM_VERSION is too low..."
else 
  echo "$RPM_VERSION is fine"
fi

Then if we were to set variables like so:

$ STR_BASE_ACCEPTABLE_VER="rpm-4.2-9.69"
$ RPM_VERSION="rpm-4.14-0.69"

$ ./cmp_rpmvers.bash    
rpm-4.14-0.69 is fine

IF I swap them:

$ STR_BASE_ACCEPTABLE_VER="rpm-4.14-0.69"
$ RPM_VERSION="rpm-4.2-9.69"

$ ./cmp_rpmvers.bash
rpm-4.2-9.69 is too low...
  • Thanks for the good info. I still need help FOR QUESTION 1: $ rpm_version=$(rpm -q --queryformat '%{VERSION}' bash gives me: 4.1.2 What I would like, is the Source RPM version. For example, for bash-4.1.2-15.el6_4.2.src.rpm I would get 4.1.2-15.el6_4.2 (all the way to src.rpm) so that I can compare to a closely related release. – bashquestion Oct 23 '14 at 2:04
  • FOR QUESTION 2: I don't have access to rpmdev-vercmp in my Linux platform, and I cannot install new components. Do you have another suggestion? – bashquestion Oct 23 '14 at 2:05
  • @bashquestion - look at the querytags. The version bits in the name of the RPM is constructed from other querytags. For eg. %{EVR}. Without rpmdev-vercmp you'll have to parse the strings manually or use sort -V command as I show in my other A that I liked to in the comments above. – slm Oct 23 '14 at 2:15
2

For Question #2 (if you don't have rpmdevtools and cannot install it):

On minimal installation you still should have yum, thus you should also have python and rpm python package. Then comparing 2 versions could look like this:

python -c "import sys,rpm; print rpm.labelCompare((None, '$VER1', '$REL1'), (None, '$VER2', '$REL2'));"

Given "rpm-4.14-0.69" package name, $VER is a version part (4.14), and $REL is a release part (0.69). You can extract them by splitting package name by '-'. I put None for epoch parts here as your example does not contain epoch in the package name.

The result of labelCompare will be 0, 1 or -1.

Actually, you could just try to download rpmdev-vercmp or rpmdev-sort (https://fedorahosted.org/releases/r/p/rpmdevtools/) and use them w/o installing rpmdevtools, as these are simple python scripts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.