Bash script to verify that an rpm is at least at a given version

11,009

Solution 1

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...

Solution 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.

Share:
11,009

Related videos on Youtube

bashquestion
Author by

bashquestion

Updated on September 18, 2022

Comments

  • bashquestion
    bashquestion over 1 year

    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
    
  • bashquestion
    bashquestion over 9 years
    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?
  • slm
    slm over 9 years
    @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.