1

I want to write a shell/bash script that can verify that all my build tools are matching certain version requirements and return pass/failed.

Example:

I use cmake, make and gcc.

$ cmake --version

cmake version 3.13.4

CMake suite maintained and supported by Kitware (kitware.com/cmake).

$ make --version

GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ gcc --version

gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In the first case, i would like to get a pass/failed whether the system matches those version numbers exactly, in the 2nd case, i would like to get a pass/failed whether the system provides minimally those versions number or newer (=greater, with respect to 1.2.2 is newer than 1.1.3).

So what i want to achieve is to:

  • step 1: identify the 3 numbers point separated version number (also allow constructs like 123.22.1)
  • step 2: split this string into 3 sections, major, minor, bugfix.

Afther that i can compare those string values against my expectation and return with a result.

Is there a simple solution with tools like awk or similar?

user654789384
  • 305
  • 1
  • 4
  • 21
  • 1
    Check [this question](https://stackoverflow.com/questions/16989598/bash-comparing-version-numbers), using `sort -V` you don't even need to bother splitting the version (you'll still need to extract the version from the tool's output, but that's easily done with one or two `grep`s, the last one using `-o`) – Aaron Nov 07 '19 at 16:13
  • 1
    This isn't a problem you want to solve at run time; it's a problem you solve at installation time using package managers, virtual environments, etc, so that your script runs in an environment where you can *assume* the correct versions are available. – chepner Nov 07 '19 at 16:16
  • 1
    I suggest not to reinvent the wheel and use `autoconf`, take a look that [this](https://stackoverflow.com/a/11071325/540286) answer. – Ortwin Angermeier Nov 07 '19 at 17:25

1 Answers1

1

Here's one way to do it, trying to implement mostly in bash (version > 4.2) using shell functions.

This doesn't return a final status code, just outputs a report to stdout.

#!/usr/bin/env bash


# Compare V1 to V2 return 2 if V2 is higher than V1
function compare_version_strings()
{
    local v1=( $(echo "$1" | tr '.' ' ') )
    local v2=( $(echo "$2" | tr '.' ' ') )
    local len=${#v1[*]}
    if [ "${#v2[*]}" -gt "$len" ] ;
    then
        len="${#v2[*]}" ;
    fi

    for ((i=0; i<len; i++))
    do
        [ "${v1[i]:-0}" -gt "${v2[i]:-0}" ] && return 1  # v1 higher
        [ "${v1[i]:-0}" -lt "${v2[i]:-0}" ] && return 2  # v2 higher
    done
    return 0 # same version
}

# Wrapper around compare_version_strings
function check_tool_version()
{
    local tool="$1" && shift
    local vmin="$1" && shift
    local vact="$1" && shift

    compare_version_strings "$vact" "$vmin"
    local result="$?"
    echo -n checking for $tool $vmin

    if [ "$result" -eq 2 ]; then
        echo " [FAIL] -- found $vact"
    else
        echo " [PASS] -- found $vact"
    fi
}


check_tool_version   cmake   3.11.2   $(cmake  --version | head -1 | awk '{print $3}')
check_tool_version   gcc     4.8      $(gcc --version | head -1 | awk '{print $3}')
check_tool_version   make    9.1      $(make --version | head -1 | awk '{print $3}')

... and example output ...

checking for cmake 3.11.2 [PASS] -- found 3.12.1
checking for gcc 4.8 [PASS] -- found 4.8.5
checking for make 9.1 [FAIL] -- found 3.82
Darren Smith
  • 2,261
  • 16
  • 16