Bash script to verify that an rpm is at least at a given version
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.
Related videos on Youtube
bashquestion
Updated on September 18, 2022Comments
-
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
-
slm over 9 years
-
bashquestion over 9 yearsFOR 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 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}
. Withoutrpmdev-vercmp
you'll have to parse the strings manually or usesort -V
command as I show in my other A that I liked to in the comments above.