如何获得Bash版本号

时间:2012-02-26 04:44:33

标签: bash shell

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

我知道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.

这可以减少到我想要的位4.2.10,由此:

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

然而,如果该消息由于某种原因而略有改变,则感觉它容易破裂。

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

8 个答案:

答案 0 :(得分:28)

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

$ echo $BASH_VERSION
4.2.8(1)-release

解析时应该更容易,更可靠。有关shell设置的环境变量列表,请参阅man page

答案 1 :(得分:23)

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

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

有关详细信息,请参阅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).

答案 2 :(得分:10)

提取第一部分:

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

答案 3 :(得分:3)

似乎有一个环境变量:

echo $BASH_VERSION

产量

4.1.7(1)-release

在我的机器上。

答案 4 :(得分:1)

运行 bash --version然后输出

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

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

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

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

4.3.30(1)-release

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

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

例如:

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

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

例如:

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

答案 5 :(得分:0)

bluecat's helpful answer

为基础

通过built-in array shell variable BASH_VERSINFO报告前3个版本号组件 - 例如4.2.10

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

如果您从Bash脚本中调用此内容,请使用子shell 以本地化更改IFS的效果:

#!/usr/bin/env bash

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

<强>解释

  • IFS=.将内部字段分隔符设置为.,这可确保当我们稍后在双引号字符串中打印数组时,数组的元素将与分离器。

    • 请注意,您不能IFS=. echo ...暂时将IFS范围重新定义为echo命令,因为shell parameter expansion${BASH_VERSINFO[*]: 0:3}的扩展,在这种情况下)在 echo被调用之前发生。因此,需要两个单独的命令;使用command substitution$(...))可确保对IFS的更改仍然是本地化的,因为命令替换在子shell中运行。
  • ${BASH_VERSINFO[*]: 0:3}从数组变量$BASH_VERSINFO中提取前3个元素(从索引0开始,返回3元素)。

    • 请注意,为了使IFS按预期工作,必须使用*而不是@来引用数组; @总是将元素分别用一个空格分隔,而不管$IFS的值。

答案 6 :(得分:0)

Bluecat's great answer上构建更多功能,该函数仅检查主要版本或主要和次要版本的组合,如果当前bash版本> =所需版本,则返回0:

check_bash_version() {
    local major=${1:-4}
    local minor=$2
    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
}

它可以被调用为:

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

答案 7 :(得分:0)

这是其他带有 BASH_VERSINFO 的响应的变体:

check_bash_version()
{
    local a=4 b=3   # Bash version >= a.b

    (( BASH_VERSINFO[0] > a || \
      (BASH_VERSINFO[0] == a && BASH_VERSINFO[1] >= b) )) || {
        echo "Error: Bash version >= $a.$b expected." >&2
        return 1
    }
}

check_bash_version || exit 1