如何在 shell 脚本中比较程序的版本?

如何在 shell 脚本中比较程序的版本?

假设我想比较gcc版本以查看系统是否安装了最低版本。

为了检查gcc版本,我执行了以下命令

gcc --version | head -n1 | cut -d" " -f4

输出是

4.8.5

所以,我写了一个简单的if语句来检查这个版本与其他值

if [ "$(gcc --version | head -n1 | cut -d" " -f4)" -lt 5.0.0 ]; then
    echo "Less than 5.0.0"
else
    echo "Greater than 5.0.0"
fi

但它会抛出一个错误:

[: integer expression expected: 4.8.5

我明白我的错误是我使用字符串进行比较并且-lt需要整数。那么,有没有其他方法来比较版本呢?

答案1

我不知道它是否漂亮,但它适用于我所知道的每个版本格式。

#!/bin/bash
currentver="$(gcc -dumpversion)"
requiredver="5.0.0"
 if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then 
        echo "Greater than or equal to ${requiredver}"
 else
        echo "Less than ${requiredver}"
 fi

笔记:用户“通配符”的更好版本:https://unix.stackexchange.com/users/135943/wildcard,删除附加条件)

答案2

较短的版本,假设 GNU sort

version_greater_equal()
{
    printf '%s\n%s\n' "$2" "$1" | sort --check=quiet --version-sort
}

version_greater_equal "${gcc_version}" 8.2 || die "need 8.2 or above"

gcc_version=008.002请注意,即使它的排序与 相同,它也会报告为不令人满意8.2。通过向 中添加-s/选项可以缓解这种情况。--stablesort

答案3

这里我给出一个比较Unix Kernel版本的解决方案。它应该适用于其他人,例如 gcc。我只关心前 2 个版本号,但您可以添加另一层逻辑。这是一行,为了便于理解,我将其写为多行。

check_linux_version() {
    version_good=$(uname -r | awk 'BEGIN{ FS="."}; 
    { if ($1 < 4) { print "N"; } 
      else if ($1 == 4) { 
          if ($2 < 4) { print "N"; } 
          else { print "Y"; } 
      } 
      else { print "Y"; }
    }')

    #if [ "$current" \< "$expected" ]; then
    if [ "$version_good" = "N" ]; then
        current=$(uname -r)
        echo current linux version too low
        echo current Linux: $current
        echo required 4.4 minimum
        return 1
    fi
}

您可以修改它并将其用于 gcc 版本检查。

答案4

function version_compare () {
  function sub_ver () {
    local len=${#1}
    temp=${1%%"."*} && indexOf=`echo ${1%%"."*} | echo ${#temp}`
    echo -e "${1:0:indexOf}"
  }
  function cut_dot () {
    local offset=${#1}
    local length=${#2}
    echo -e "${2:((++offset)):length}"
  }
  if [ -z "$1" ] || [ -z "$2" ]; then
    echo "=" && exit 0
  fi
  local v1=`echo -e "${1}" | tr -d '[[:space:]]'`
  local v2=`echo -e "${2}" | tr -d '[[:space:]]'`
  local v1_sub=`sub_ver $v1`
  local v2_sub=`sub_ver $v2`
  if (( v1_sub > v2_sub )); then
    echo ">"
  elif (( v1_sub < v2_sub )); then
    echo "<"
  else
    version_compare `cut_dot $v1_sub $v1` `cut_dot $v2_sub $v2`
  fi
}

### Usage:

version_compare "1.2.3" "1.2.4"
# Output: <

信用去往@谢尔曼

相关内容