SKYnine
SKYnine

Reputation: 2708

shell script condition for version number

I'm really new to shell script and I would like to check for software version number and set condition upon it.

ex: check if python version > 2.7.0 then ...

I can check for python using this:

if [ "$(python -V 2>&1)" ]
then
    pyv="$(python -V 2>&1)"
    echo "$pyv"
fi

Upvotes: 1

Views: 100

Answers (1)

John1024
John1024

Reputation: 113834

Python's output is not immediately useful:

$ python -V
Python 2.7.9

The output includes a word, Python, and a version number. Further, because the version number has two decimal points, it is not a valid number.

Approach 1: using bc

One approach is to convert the version into a valid decimal number:

$ python -V 2>&1 | awk -F'[ .]' '{printf "%s.%s%02.f",$2,$3,$4}'
2.709

In this form, version 2.7.10 would become 2.710. This approach works up through point version of 99. If you think there is a chance that python will release a point version 100, then we would want to change the format slightly.

We can now compare number using bc:

$ echo "$(python -V 2>&1 | awk -F'[ .]' '{printf "%s.%s%02.f",$2,$3,$4}') > 2.7" | bc -l
1
$ echo "$(python -V 2>&1 | awk -F'[ .]' '{printf "%s.%s%02.f",$2,$3,$4}') > 2.710" | bc -l
0

To use that in an if statement:

if echo "$(python -V 2>&1 | awk -F'[ .]' '{printf "%s.%s%02.f",$2,$3,$4}') > 2.7" | bc -l | grep -q 1
then
    echo version greater than 2.7
fi

If the test is successful, bc -l prints a 1 to standard out. To silently test for the presence of 1, we use grep -q 1.

Approach 2: using integer comparison

We use awk to convert the version number to an integer form:

$ python -V 2>&1 | awk -F'[ .]' '{printf "%2.f%02.f%02.f",$2,$3,$4}'
 20709

Now, we can use standard shell tools to test the version:

if [ "$(python -V 2>&1 | awk -F'[ .]' '{printf "%2.f%02.f%02.f",$2,$3,$4}')" -gt 20700 ]
then
   echo version greater than 2.7
fi

Approach 3: using GNU sort -V

GNU sort has a version sorting feature. To use it, we create input useful for version sorting:

$ t="Python 2.7.0"
$ echo "$(python -V 2>&1)"$'\n'"$t" | sort -V -k2,2
Python 2.7.0
Python 2.7.9

Now, we sort in ascending order:

$ echo "$(python -V 2>&1)"$'\n'"$t" | sort -V -k2,2
Python 2.7.0
Python 2.7.9

If the first line is $t, that means that the actual python version is newer:

t="Python 2.7.0"
if echo "$(python -V 2>&1)"$'\n'"$t" | sort -V -k2,2 | head -n1 | grep -q "$t"
then
    echo "version greater than $t"
fi

Since GNU sort -V is designed to handle version numbers natively, this is the approach that I prefer.

Upvotes: 5

Related Questions