• VMware

    Learn about VMware virtualization for its products like vsphere ESX and ESXi, vCenter Server, VMware View, VMware P2V and many more

  • Linux

    Step by step configuration tutorials for many of the Linux services like DNS, DHCP, FTP, Samba4 etc including many tips and tricks in Red Hat Linux.

  • Database

    Learn installation and configuration of databases like Oracle, My SQL, Postgresql, etc including many other related tutorials in Linux.

  • How to check and compare rpm version and release in Linux using bash script



    Recently I came into a situation where I was supposed to install a hotfix patch on my Linux setup where I was supposed to programmatically compare the version of all the available rpms with the list of rpms downloaded from the yum repository. Now in most organization the linux servers would not be connected to internet hence the comparing part needs to be done manually.

    Now I have an excel sheet which has 1000+ rpms and on my setup I have around 400+ rpms installed. Now I should compare rpms at both places and if any new rpm is found then update the same.





    Comparing rpm versions is very tricky as each one has their own syntax and they do not follow a general syntax or naming convention other than the below format
    name-release-version.arch

    But here each section can be different.
    With Red Hat we have a tool "rpmdev-vercmp" which is part of "yum-utils" rpm

    This tool can be used to perform the comparison
    # rpmdev-vercmp python-chardet-2.2.1-1.el7_1.noarch python-chardet-2.2.1-1.el7_2.noarch
    python-chardet-2.2.1-1.el7_1.noarch < python-chardet-2.2.1-1.el7_2.noarch

    But my fade of luck, I am not allowed to install this additional rpm. So I decided to write my own algorithm to compare rpm versions and I came up with below script
    #!/bin/bash

    # Get both the package detail and store them in their respective variable
    pkg1="$1"
    pkg2="$2"

    # Check if rpm is installed
    function check_rpm_status {
     rpm -q $1 | grep -v "not installed" >/dev/null 2>&1
     if [ $? == "0" ];then
        return 0
     else
        return 1
     fi
    }

    function get_rpm_version {
     python -c "print '-'.join('$1'.rsplit('-',2)[-2:])"
    }

    # Get the version and release detail of both the packages
    if check_rpm_status $pkg1;then
        pkg1_ver=`rpm -q --queryformat "%{VERSION}-%{RELEASE}.%{ARCH}\n" $pkg1`
    else
        pkg1_ver=$(get_rpm_version $pkg1)
    fi

    if check_rpm_status $pkg2;then
        pkg2_ver=`rpm -q --queryformat "%{VERSION}-%{RELEASE}.%{ARCH}\n" $pkg2`
    else
        pkg2_ver=$(get_rpm_version $pkg2)
    fi

    # Modify the collected version and release detail to further compare them
    pkg1_ver_modified=`echo $pkg1_ver | sed -E -e 's/.el[0-9]|.x86_64|.i[0-9]86|.noarch//g; s/-|_/./g; s/[a-z]//g'`
    pkg2_ver_modified=`echo $pkg2_ver | sed -E -e 's/.el[0-9]|.x86_64|.i[0-9]86|.noarch//g; s/-|_/./g; s/[a-z]//g'`

    # Store the version into array for comparison
    IFS="." read -a pkg1_array <<< ${pkg1_ver_modified}
    IFS="." read  -a pkg2_array<<< ${pkg2_ver_modified}

    # Collect the result and store in these variables
    both_are_equal=0
    pkg1_is_greater=0
    pkg2_is_greater=0

    # Main
    for ((i=0; i<${#pkg1_array[@]} || i<${#pkg2_array[@]}; i++)); do
      [[ ${pkg1_array[$i]} -eq ${pkg2_array[$i]} ]] && ((both_are_equal++))
      if [[ ${pkg1_array[$i]} -gt ${pkg2_array[$i]} ]];then
         ((pkg1_is_greater++))
         break
      fi
      [[ ${pkg1_array[$i]} -lt ${pkg2_array[$i]} ]] && ((pkg2_is_greater++))
    done


    if [[ ${#pkg2_array[@]} -eq ${#pkg1_array[@]} && ${#pkg1_array[@]} -eq $both_are_equal ]];then
       echo "$pkg1 is equal to $pkg2"
    elif [[ $pkg1_is_greater -gt "0" && $pkg2_is_greater -eq "0" ]];then
       echo "$pkg1 > $pkg2"
    else
       echo "$pkg1 < $pkg2"
    fi

    This script will work same as "rpmdev-vercmp" tool.



    Syntax:
    /tmp/compare-rpm.sh $pkg1 $pkg2

    Below are some examples I tried for various types of rpms
    # ./compare-rpm.sh libssh2-1.4.13-4.el7_1.20.x86_64 libssh2-1.4.13-13.el7_1.20.x86_64
    libssh2-1.4.13-4.el7_1.20.x86_64 < libssh2-1.4.13-13.el7_1.20.x86_64

    # ./compare-rpm.sh selinux-policy-targeted-3.13.1-166.el7.noarch selinux-policy-targeted-3.12.1-166.el7.noarch
    selinux-policy-targeted-3.13.1-166.el7.noarch > selinux-policy-targeted-3.12.1-166.el7.noarch

    # ./compare-rpm.sh plymouth-core-libs-0.8.9-0.28.20140113.el7.x86_64 plymouth-core-libs-0.8.10-0.28.20140114.el7.x86_64
    plymouth-core-libs-0.8.9-0.28.20140113.el7.x86_64 < plymouth-core-libs-0.8.10-0.28.20140114.el7.x86_64

    # ./compare-rpm.sh net-tools-2.0-0.22.20131004git.el7.x86_64 net-tools-2.0-0.22.20141004git.el7.x86_64
    net-tools-2.0-0.22.20131004git.el7.x86_64 < net-tools-2.0-0.22.20141004git.el7.x86_64

    # ./compare-rpm.sh Red_Hat_Enterprise_Linux-Release_Notes-7-en-US-7-2.el7.noarch Red_Hat_Enterprise_Linux-Release_Notes-7-en-US-7-3.el7.noarch
    Red_Hat_Enterprise_Linux-Release_Notes-7-en-US-7-2.el7.noarch < Red_Hat_Enterprise_Linux-Release_Notes-7-en-US-7-3.el7.noarch

    # ./compare-rpm.sh  linux-firmware-20170606-56.gitc990aae.el7.noarch linux-firmware-20170606-56.gitc998aae.el7.noarch
    linux-firmware-20170606-56.gitc990aae.el7.noarch < linux-firmware-20170606-56.gitc998aae.el7.noarch

    Atleast this tool worked for me, I hope this can be useful to others reading this article.

    Please share your feedback if you face any issues with this script, we can try to make this more robust.

    Deepak Prasad

    is a techie and an author who is still trying to survive in this IT generation with very little knowledge he has on Linux/Unix, VMware, SAN Storage, Automation, networking etc

    You can follow him on Facebook or Google+

    Do you also have something to share here?

    Join GoLinuxHub Team as an Author, Click here for more information
    How to check and compare rpm version and release in Linux using bash script How to check and compare rpm version and release in Linux using bash script Reviewed by Deepak Prasad on Thursday, June 28, 2018 Rating: 5

    No comments:

    Powered by Blogger.