我正在为一个需要Flex和Bison 2.5或更高版本的程序编写一个BASH安装程序脚本。
我已经有了检查flex
和bison
是否已经安装的代码。
我不确定这在所有版本中是否保持不变,但是下面分别是flex --version
和bison --version
的输出:
➜ ~ flex --version
flex 2.5.35
➜ ~ bison --version
bison (GNU Bison) 2.5
Written by Robert Corbett and Richard Stallman.
Copyright (C) 2011 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.
是否有“正确”的检查方法,以确保系统有flex和bison 2.5或更高版本
发布于 2012-07-22 18:16:21
由于bash不处理浮点数,所以可以在awk中进行实际比较。
for cmd in flex bison; do
[[ $("$cmd" --version) =~ ([0-9][.][0-9.]*) ]] && version="${BASH_REMATCH[1]}"
if ! awk -v ver="$version" 'BEGIN { if (ver < 2.5) exit 1; }'; then
printf 'ERROR: %s version 2.5 or higher required\n' "$cmd"
fi
done
为了使其在纯bash中工作,需要对每个数字进行单独比较:
req_version=(2 5)
for cmd in flex bison; do
[[ $("$cmd" --version) =~ ([0-9][.][0-9.]*) ]] && IFS=. read -ra version <<< "${BASH_REMATCH[1]}"
for (( i=0; i < "${#req_version[@]}"; i++)); do
if (( "${req_version[i]}" > "${version[i]}" )); then
printf 'ERROR: %s version 2.5 or higher required\n' "$cmd"
exit 1
fi
done
done
发布于 2012-07-22 17:14:01
您可以考虑使用自动工具。然后,您将有预定义的宏来测试是否存在flex和野牛。
AX_PROG_FLEX(ACTION-IF-TRUE,ACTION-IF-FALSE)
AX_PROG_BISON(ACTION-IF-TRUE,ACTION-IF-FALSE)
不幸的是,您似乎无法测试给定的版本。但是负责测试bison和flex存在的m4宏非常短,所以您可以很容易地修改它们。通过查看autotools查找给定版本的C++ Boost库的方式,您可能会得到一些关于如何做到这一点的灵感。实际上,如果您想出了在autotools中包含flex和bison版本测试的修改,您可以考虑提供解决方案:)
您还可以通过使用自动工具获得许多其他好处。具体来说,您将使用一个经过高度测试和可移植的环境来构建和安装应用程序。
如果您更喜欢使用自定义bash安装工具,那么我认为使用--version
并解析结果(例如使用正则表达式)已经是一种合适的方法。大多数(如果不是全部) GNU应用程序很久以前就支持将--version
命令作为检查实际程序版本的标准方法。
发布于 2012-07-22 19:29:19
如果提取了两个版本号,则可以将它们与如下脚本进行比较:
#!/usr/bin/env perl
#
# Compare two version numbers:
# Exit status 0 equal; 1 if first is larger, 2 if second is larger.
use strict;
use warnings;
die "Usage: $0 ver1 ver2\n" if (scalar(@ARGV) != 2);
my @v1 = split /[._-]/, $ARGV[0];
my @v2 = split /[._-]/, $ARGV[1];
my $n1 = scalar(@v1);
my $n2 = scalar(@v2);
my $n = $n1 < $n2 ? $n1 : $n2;
my $rc = 0;
for (my $i = 0; $i < $n && $rc == 0; $i++)
{
$rc = 1 if ($v1[$i] > $v2[$i]);
$rc = 2 if ($v2[$i] > $v1[$i]);
}
if ($rc == 0 && $n1 != $n2)
{
$rc = ($n1 > $n2) ? 1 : 2;
}
exit $rc;
使用实例
$ vercmp 2.3.5 2.3.5; echo $?
0
$ vercmp 2.3.35 2.3.5; echo $?
1
$ vercmp 2.5.35 2.3.5; echo $?
1
$ vercmp 2.5.35 2.6.5; echo $?
2
$
它成功地处理了很多奇怪的版本号比较,但可能不是所有的东西。您可以设计它,使它回显状态(0,1,2),而不是退出不同的状态。
在CPAN中也有许多“版本”模块可用。
https://stackoverflow.com/questions/11601885
复制相似问题