如何获取 Bash 版本号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9450604/
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-09 21:42:09  来源:igfitidea点击:

How to get Bash version number

bashshell

提问by stwalkerster

I'm writing a script which requires the bash version number in a simple short format.

我正在编写一个脚本,它需要一个简单的短格式的 bash 版本号。

I'm aware of bash --version, but this gives a long output:

我知道bash --version,但这给出了很长的输出:

GNU bash, version 4.2.10(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

This could be cut down to the bit I want, 4.2.10, by this:

这可以通过以下方式减少到我想要的程度4.2.10

bash --version | grep "bash" | cut -f 4 -d " " | cut -d "-" -f 1  | cut -d "(" -f 1

However, this feels like it would be prone to break if that message ever changed slightly for whatever reason.

但是,如果该消息因任何原因稍有更改,则感觉它很容易中断。

Is there a better way to do this, and what is this better way?

有没有更好的方法来做到这一点,这个更好的方法是什么?

回答by Mansoor Siddiqui

If you're running within a bash shell, then the $BASH_VERSIONenvironment variable should be set:

如果您在 bash shell 中运行,$BASH_VERSION则应设置环境变量:

$ echo $BASH_VERSION
4.2.8(1)-release

That should be easier and more reliable to parse. See the man pagefor a list of environment variables set by the shell.

这应该更容易和更可靠地解析。有关shell 设置的环境变量列表,请参阅手册页

回答by FelixEnescu

There's also a special array (BASH_VERSINFO) containing each version number in separate elements.

还有一个特殊的数组 (BASH_VERSINFO) 在单独的元素中包含每个版本号。

if ((BASH_VERSINFO[0] < 3))
then 
  echo "Sorry, you need at least bash-3.0 to run this script." 
  exit 1 
fi

See http://www.tldp.org/LDP/abs/html/internalvariables.htmlfor more info:

有关更多信息,请参阅http://www.tldp.org/LDP/abs/html/internalvariables.html

# Bash version info:

for n in 0 1 2 3 4 5
do
  echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}"
done  

# BASH_VERSINFO[0] = 3                      # Major version no.
# BASH_VERSINFO[1] = 00                     # Minor version no.
# BASH_VERSINFO[2] = 14                     # Patch level.
# BASH_VERSINFO[3] = 1                      # Build version.
# BASH_VERSINFO[4] = release                # Release status.
# BASH_VERSINFO[5] = i386-redhat-linux-gnu  # Architecture
                                            # (same as $MACHTYPE).

回答by kev

To extract the first part:

提取第一部分:

$ echo ${BASH_VERSION%%[^0-9.]*}
4.2.10

回答by jogojapan

There seems to be an environment variable for this:

似乎有一个环境变量:

echo $BASH_VERSION

yields

产量

4.1.7(1)-release

on my machine.

在我的机器上。

回答by codeforester

Building more on Bluecat's great answer, here is a function that checks for just the major version or a combination of major and minor versions and returns 0 if the current bash version is >= the needed version:

Bluecat 的好答案上构建更多内容,这里有一个函数,它只检查主要版本或主要和次要版本的组合,如果当前 bash 版本 >= 所需版本,则返回 0:

check_bash_version() {
    local major=${1:-4}
    local minor=
    local rc=0
    local num_re='^[0-9]+$'

    if [[ ! $major =~ $num_re ]] || [[ $minor && ! $minor =~ $num_re ]]; then
        printf '%s\n' "ERROR: version numbers should be numeric"
        return 1
    fi
    if [[ $minor ]]; then
        local bv=${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}
        local vstring=$major.$minor
        local vnum=$major$minor
    else
        local bv=${BASH_VERSINFO[0]}
        local vstring=$major
        local vnum=$major
    fi
    ((bv < vnum)) && {
        printf '%s\n' "ERROR: Need Bash version $vstring or above, your version is ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}"
        rc=1
    }
    return $rc
}

It can be invoked as:

它可以被调用为:

check_bash_version 4   # check if 4.0 or above
check_bash_version 4 2 # check if 4.2 or above


See the assertion related to this:

请参阅与此相关的断言:

https://github.com/codeforester/base/blob/f230fbacbb1d9fe48d68ce9302902fe2d3785dde/lib/assertions.sh#L12

https://github.com/codeforester/base/blob/f230fbacbb1d9fe48d68ce9302902fe2d3785dde/lib/assertions.sh#L12

回答by codeforester

runbash --versionthen its output likes

运行bash --version然后它的输出喜欢

GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)

or

或者

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

or

或者

GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)


usebash variable $BASH_VERSION, run echo $BASH_VERSION, its output likes

使用bash 变量$BASH_VERSION,运行echo $BASH_VERSION,它的输出喜欢

4.3.30(1)-release


UsuallyI use command sedto extract the version no., following is concrete command:

通常我使用命令sed来提取版本号,以下是具体命令:

bash --version | sed -r -n 's@.*version (.*)\(1\)-release.*@\1@p'

bash --version | sed -r -n 's@.*version (.*)\(1\)-release.*@\1@p'

eg:

例如:

[flying@lempstacker ~]$ bash --version | sed -r -n 's@.*version (.*)\(1\)-release.*@@p'
4.2.46
[flying@lempstacker ~]$ 

echo $BASH_VERSION | sed -r -n 's@(.*)\(1\)-release.*@\1@p'

echo $BASH_VERSION | sed -r -n 's@(.*)\(1\)-release.*@\1@p'

eg:

例如:

[flying@lempstacker ~]$ echo $BASH_VERSION | sed -r -n 's@(.*)\(1\)-release.*@@p'
4.2.46
[flying@lempstacker ~]$ 

回答by mklement0

Building on bluecat's helpful answer:

bluecat 的有用答案为基础

To report the first 3 version-number components - e.g., 4.2.10- via built-in array shell variable BASH_VERSINFO:

要报告前 3 个版本号组件 - 例如4.2.10- 通过内置数组 shell 变量BASH_VERSINFO

$ bash -c 'IFS=.; echo "${BASH_VERSINFO[*]: 0:3}"'
4.2.10

If you're calling this from inside a Bash script, use a subshellin order to localize the effect of changing IFS:

如果您从 Bash 脚本内部调用它,请使用子shell以本地化更改的效果IFS

#!/usr/bin/env bash

ver=$(IFS=.; echo "${BASH_VERSINFO[*]: 0:3}")  # -> e.g., $ver == '4.2.10'

Explanation:

解释:

  • IFS=.sets the internal field separator to ., which ensures that when we print an array inside a double-quoted string later, the array's elements are joined with that separator.

    • Note that you can't just do IFS=. echo ...to transiently redefine IFS scoped to the the echocommand, because shell parameter expansion(the expansion of ${BASH_VERSINFO[*]: 0:3}, in this case) happens beforeechois invoked. Therefore, two separate command are needed; the use of a command substitution($(...)) ensures that the change to IFSis still localized, because command substitutions run in subshells.
  • ${BASH_VERSINFO[*]: 0:3}extracts the first 3 elements from array variable $BASH_VERSINFO(starting at index 0, return 3elements).

    • Note that in order for IFSto work as intended, *rather than @must be used to reference the array; @would invariablyseparate the elements with a single space each, irrespective of the value of $IFS.
  • IFS=.将内部字段分隔符设置为.,这确保当我们稍后在双引号字符串中打印数组时,数组的元素与该分隔符连接。

    • 请注意,您不能只是IFS=. echo ...暂时重新定义范围为echo命令的IFS ,因为 shell参数扩展${BASH_VERSINFO[*]: 0:3}在本例中为 的扩展)发生echo调用之前。因此,需要两个单独的命令;使用的命令替换$(...))可以确保对变更IFS还是局部的,因为指令置换在子shell运行。
  • ${BASH_VERSINFO[*]: 0:3}从数组变量中提取前 3 个元素$BASH_VERSINFO(从 index 开始0,返回3元素)。

    • 请注意,为了IFS按预期工作,*而不是@必须使用来引用数组;@总是元件与每个单个空格分开的值无关,$IFS