Comparing Version Strings with Bash

by Louis Marascio on May 20, 2011

This post is part of a series: Bash Tips and Tricks.

When I write a “serious” bash script I always try to check my pre-requisites. Is pigz installed? If not, fall back to gzip. Is wget installed? If not, error out. That sort of stuff. One part of this is checking the version of the programs you depend on. Most of the time version doesn’t matter, but every so often it does. There are some tools out there to do version comparisons, like Arch’s vercmp. However, I’ve never really found a ubiquitous tool that I could rely on being there, so I decided to write a bash function to do the comparison for me that relies only on sed, sort, and head–tools that are ubiquitous.

# return 0 if program version is equal or greater than check version
check_version()
{
    local version=$1 check=$2
    local winner=$(echo -e "$version\n$check" | sed '/^$/d' | sort -nr | head -1)
    [[ "$winner" = "$version" ]] && return 0
    return 1
}

The function, check_version, takes two arguments. The first is the version of the tool we are verifying and the second is the minimum version we’re willing to accept. Both version and check must only be major.minor version numbers, no patch levels, beta tags, or any other “version chrome”. The way it works is very simple:

  1. Echo both versions one on each line, and send that as stdin to sed.
  2. Eliminate empty lines with sed.
  3. Use sort to do a reverse numeric sort.
  4. Take the first line of sort‘s output, and call that the winner.
  5. If the winner is the version from the tool we are verifying, the one passed in as argument 1, then the version of the tool checks out. Otherwise, it does not.

This function does exactly what I need, nothing more and nothing less. I’m sure it could be extended to support more than major/minor version numbers. If you do add features to it, please let me know.

  • Friend

    This will not work for version strings, even simple major.minor ones.  Try it with “check_version 1.19 1.9″.  Instead I used “sort -t. -k1,1nr -k2,2nr”.

  • Aaa

    To Friend : Better still, use sort -Vr

Previous post:

Next post: