Here's how to compare versions.
using sort -V
:
function version_gt() { test "$(printf '%s
' "$@" | sort -V | head -n 1)" != "$1"; }
example usage:
first_version=5.100.2
second_version=5.1.2
if version_gt $first_version $second_version; then
echo "$first_version is greater than $second_version !"
fi
pro:
- solid way to compare fancy version strings:
- support any length of sub-parts (ie: 1.3alpha.2.dev2 > 1.1 ?)
- support alpha-betical sort (ie: 1.alpha < 1.beta2)
- support big size version (ie: 1.10003939209329320932 > 1.2039209378273789273 ?)
- can easily be modified to support n arguments. (leaved as an exercise ;) )
- usually very usefull with 3 arguments: (ie: 1.2 < my_version < 2.7 )
cons:
- uses a lot of various calls to different programs. So it's not that efficient.
- uses a pretty recent version of
sort
and it might not be available on your
system. (check with man sort
)
without sort -V
:
## each separate version number must be less than 3 digit wide !
function version { echo "$@" | gawk -F. '{ printf("%03d%03d%03d
", $1,$2,$3); }'; }
example usage:
first_version=5.100.2
second_version=5.1.2
if [ "$(version "$first_version")" -gt "$(version "$second_version")" ]; then
echo "$first_version is greater than $second_version !"
fi
pro:
- quicker solution as it only calls 1 subprocess
- much more compatible solution.
cons:
- quite specific, version string must:
- have version with 1, 2 or 3 parts only. (excludes '2.1.3.1')
- each parts must be numerical only (excludes '3.1a')
- each part can't be greater than 999 (excludes '1.20140417')
Comments about your script:
I can't see how it could work:
- as stated in a comment
>
and <
are very special shell character and you should replace them by -gt
and -lt
- even if you replaced the characters, you can't compare version numbers as if they where integers or float. For instance, on my system, php version is
5.5.9-1ubuntu4
.
But your function version()
is quite cleverly written already and may help you by circumventing the classical issue that sorting alphabetically numbers won't sort numbers numerically ( alphabetically 1 < 11 < 2, which is wrong numerically). But be carefull: arbitrarily large numbers aren't supported by bash (try to keep under 32bits if you aim at compatibility with 32bits systems, so that would be 9 digit long numbers). So I've modified your code (in the second method NOT using sort -V
) to force only 3 digits for each part of the version string.
EDIT: applied @phk amelioration, as it is noticeably cleverer and remove a subprocess call in the first version using sort
. Thanks.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…