BASH比较版本号

ehi*_*ime 33 bash shell

嘿大家我有这个脚本,应该确保用户当前的PHP版本在一定范围之间,虽然它应该工作,有一个错误,使它认为版本超出范围,有人可以看看,告诉我我能做些什么来解决它?

function version { echo "$@" | gawk -F. '{ printf("%d.%d.%d\n", $1,$2,$3); }'; }

phpver=`php -v |grep -Eow '^PHP [^ ]+' |gawk '{ print $2 }'`

if [ $(version $phpver) > $(version 5.2.13) ] || [ $(version $phpver) < $(version 5.2.13) ]; then
  echo "PHP Version $phpver must be between 5.2.13 - 5.3.15"
  exit
fi
Run Code Online (Sandbox Code Playgroud)

vaa*_*aab 89

以下是比较版本的方法.

使用sort -V:

function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
Run Code Online (Sandbox Code Playgroud)

示例用法:

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
Run Code Online (Sandbox Code Playgroud)

亲们:

  • 比较花哨版本字符串的可靠方法:
    • 支持任何长度的子部分(即:1.3alpha.2.dev2> 1.1?)
    • 支持alpha-betical排序(即:1.alpha <1.beta2)
    • 支持大尺寸版本(即:1.10003939209329320932> 1.2039209378273789273?)
  • 可以很容易地修改以支持n个参数.(作为练习留下;))
    • 通常非常有用3个参数:(即:1.2 <my_version <2.7)

缺点:

  • 对不同的程序使用了很多不同的调用.所以效率不高.
  • 使用最近的版本,sort它可能在您的系统上不可用.(检查man sort)

没有sort -V:

## each separate version number must be less than 3 digit wide !
function version { echo "$@" | gawk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; }
Run Code Online (Sandbox Code Playgroud)

示例用法:

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
Run Code Online (Sandbox Code Playgroud)

亲们:

  • 更快的解决方案,因为它只调用1个子进程
  • 更兼容的解决方案.

缺点:

  • 非常具体,版本字符串必须:
    • 只有1,2或3个版本的版本.(不包括'2.1.3.1')
    • 每个部分必须只是数字(不包括'3.1a')
    • 每个部分不能大于999(不包括'1.20140417')

关于你的脚本的评论:

我看不出它是如何工作的:

  • 如注释中所述>并且<是非常特殊的shell字符,您应该用-gt和替换它们-lt
  • 即使您替换了字符,也无法比较版本号,就好像它们是整数或浮点数一样.例如,在我的系统上,php版本是5.5.9-1ubuntu4.

但是你的功能version()已经非常巧妙地编写了,并且可以通过规避经典问题来帮助你,即按字母顺序排序数字不会对数字进行数字排序(按字母顺序1 <11 <2,这在数字上是错误的).但要小心:bash不支持任意大数(如果你的目标是与32位系统兼容,那么试着保持在32位以下,这样就是9位长的数字).所以我修改了你的代码(在第二种方法中不使用sort -V)来强制版本字符串的每个部分只有3位数.

编辑:应用@phk改进,因为它显然更聪明,并使用在第一个版本中删除子进程调用sort.谢谢.

  • 你可以替换`echo "$@" | tr " " "\n"` 和 `printf '%s\n' "$@"` 效果更好(例如,如果版本号字符串以 `-` 开头)并且只需要一次调用。 (2认同)

And*_*rey 14

deb分布有可能:

dpkg --compare-versions <version> <relation> <version>
Run Code Online (Sandbox Code Playgroud)

例如:

dpkg --compare-versions "0.0.4" "gt" "0.0.3"
if [ $? -eq "0" ]; then echo "YES"; else echo "NO"; fi
Run Code Online (Sandbox Code Playgroud)