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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11601885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:51:11  来源:igfitidea点击:

Check if the right versions of Flex and Bison are installed

bashunixbisonflex-lexer

提问by Aaron Yodaiken

I'm writing a BASH installer script for a program the requires Flex and Bison version 2.5 or higher.

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

I've already got the code to check that flexand bisonare installed at all.

我已经有代码来检查flexbison安装了。

I'm not sure if this has stayed constant throughout the versions but here are the outputs of flex --versionand bison --versionrespectively:

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

Is there a "right" way to check to make sure that the system has flex and bison 2.5 or higher?

是否有“正确”的方法来检查以确保系统具有 flex 和 bison 2.5或更高版本

采纳答案by jordanm

Since bash doesn't handle floating point numbers, you can do the actual comparison in awk.

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

In order to get this to work in pure bash, each number needs to be compared individually:

为了让它在纯 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

回答by betabandido

You may consider using autotools. Then you will have predefined macros to test for the presence of flexand bison:

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

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

Unluckily it seems you cannot test for a given version. But the m4 macros responsible for testing for the presence of bison and flex are very short, so you may easily modify them. You may get some inspiration on how to do that by having a look at the way autotools look for a given version of C++ Boost library. Actually, if you come up with a modification for including version testing for flex and bison in autotools, you may consider contributing your solution :)

不幸的是,您似乎无法测试给定的版本。但是负责测试 bison 和 flex 是否存在的 m4 宏非常短,因此您可以轻松修改它们。通过查看autotools 查找给定版本的 C++ Boost 库方式,您可能会获得一些关于如何做到这一点的灵感。实际上,如果您想出修改以在 autotools 中包含 flex 和 bison 的版本测试,您可以考虑贡献您的解决方案:)

You will also get many other benefits by using autotools. Specifically, you will be using a highly tested and portable environment for building and installing applications.

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

If you prefer to do a custom bash installing tool, then I would say using --versionand parsing the result (by using a regular expression, for instance) is already an appropriate way to do so. Most (if not all) GNU applications support since long time ago the --versioncommand as the standard way to check for the actual program version.

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

回答by Jonathan Leffler

If you have two version numbers extracted, you can compare them with a script such as this:

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

#!/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: 
$ 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
$
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;

Examples of use

使用示例

##代码##

It manages to deal with an awful lot of weird version number comparisons, but probably not everything. You could design it so that it echoes the status (0, 1, 2) instead of exiting with the different statuses.

它设法处理了大量奇怪的版本号比较,但可能不是全部。您可以对其进行设计,使其与状态 (0, 1, 2) 相呼应,而不是以不同的状态退出。

There are also numerous 'version' modules available at CPAN.

CPAN上还有许多“版本”模块可用。