我正在为需要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
答案 0 :(得分:2)
您可以考虑使用autotools。然后,您将拥有预定义的宏来测试是否存在flex和bison:
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还提供了许多“版本”模块。