检查是否安装了正确版本的Flex和Bison

时间:2012-07-22 16:13:58

标签: bash unix bison flex-lexer

我正在为需要Flex和Bison 2.5或更高版本的程序编写BASH安装程序脚本。

我已经有代码检查是否安装了flexbison

我不确定这是否在整个版本中保持不变,但这里分别是flex --versionbison --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 或更高?

3 个答案:

答案 0 :(得分:2)

您可以考虑使用autotools。然后,您将拥有预定义的宏来测试是否存在flexbison

AX_PROG_FLEX(ACTION-IF-TRUE,ACTION-IF-FALSE)
AX_PROG_BISON(ACTION-IF-TRUE,ACTION-IF-FALSE)

不幸的是,您似乎无法测试给定版本。但负责测试野牛和flex的存在的m4宏非常短,因此您可以轻松修改它们。您可以通过查看way autotools look for a given version of C++ Boost library获得有关如何做到这一点的灵感。实际上,如果您想要在自动工具中包含flex和bison版本测试的修改,您可以考虑提供解​​决方案:)

使用autotools还可以获得许多其他好处。具体来说,您将使用经过高度测试和可移植的环境来构建和安装应用程序。

如果您更喜欢使用自定义bash安装工具,那么我会说使用--version并解析结果(例如使用正则表达式)已经是一种合适的方法。大多数(如果不是全部)GNU应用程序支持很久以前--version命令作为检查实际程序版本的标准方法。

答案 1 :(得分:2)

由于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

答案 2 :(得分:0)

如果您提取了两个版本号,则可以将它们与以下脚本进行比较:

#!/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还提供了许多“版本”模块。