从BASH脚本检查Java版本的正确方法

Aar*_*lla 53 java bash version dependency-management

如何从bash脚本检查Java是否可用(在PATH中或通过JAVA_HOME)并确保版本至少为1.5?

gle*_*man 78

也许是这样的:

if type -p java; then
    echo found java executable in PATH
    _java=java
elif [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]];  then
    echo found java executable in JAVA_HOME     
    _java="$JAVA_HOME/bin/java"
else
    echo "no java"
fi

if [[ "$_java" ]]; then
    version=$("$_java" -version 2>&1 | awk -F '"' '/version/ {print $2}')
    echo version "$version"
    if [[ "$version" > "1.5" ]]; then
        echo version is more than 1.5
    else         
        echo version is less than 1.5
    fi
fi
Run Code Online (Sandbox Code Playgroud)

  • "`type -p java`"在"sh"中不起作用; 所以,为了便于携带,在脚本中使用`#!/ bin/bash`,而不是`#!/ bin/sh`(但是,`/ bin/sh`实际上可能不是bourne shell,而是向后兼容的变体) (3认同)
  • 为了比较版本,我建议:`version1 = $(echo"$ version"| awk -F.'{printf("%03d%03d",$ 1,$ 2);}')`这将使你主要和次要对齐每个都有3位数,然后与`if [$ version1 -ge 001008]进行比较; then` (3认同)
  • 呃抱歉不能得到评论格式。当 Java 版本为 1.10 时,这会失败。这是因为字符串comapre 不是数字比较。当版本为“1.5”时,答案也是错误的,虽然我猜那会是“1.5.0”,所以我猜它没问题。 (2认同)

Mic*_*jer 46

您可以通过以下方式获取Java版本

JAVA_VER=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;')
Run Code Online (Sandbox Code Playgroud)

它会为你16提供类似的java 1.6.0_1315版本1.5.0_17.

所以你可以在shell中轻松比较它:

[ "$JAVA_VER" -ge 15 ] && echo "ok, java is 1.5 or newer" || echo "it's too old..."
Run Code Online (Sandbox Code Playgroud)

更新: 此代码应该与注释中提到的openjdk和JAVA_TOOL_OPTIONS一起使用.

  • OpenJDK 8的'java -version'结果略有不同,输出中"java"被"openjdk"取代.这个表达式适用于两种情况:`sed's /.*version"\(.*\)\.\(.*\)\ ..*"/\1\2 /; 1q'` (8认同)
  • 自 java 9 以来,这不再正常工作,并且自 java 10 以来失败了 (2认同)

dvl*_*ube 20

上述答案仅适用于特定的 Java 版本(通常适用于 Java 9 之前的版本或 Java 8 之后的版本。

我写了一个简单的单行代码,它将为 Java 版本 6 到 11(可能还有所有未来版本,直到他们再次更改它!)返回一个整数。

它基本上去掉了“1”。在版本号的开头,如果存在,则只考虑下一个“.”之前的第一个数字。

java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1


Jig*_*shi 16

您可以发出java -version并读取和解析输出

java -version 2>&1 >/dev/null | grep 'java version' | awk '{print $3}'
Run Code Online (Sandbox Code Playgroud)

  • 如果只对数字部分感兴趣并在路径变量中进一步使用,您可以使用类似`java -version 2>&1 | 的内容。头-1 | cut -d '"' -f 2` (2认同)

Seb*_*ian 11

您还可以将 jdk 类版本号与以下内容进行比较javap

javap -verbose java.lang.String | grep "major version" | cut -d " " -f5
Run Code Online (Sandbox Code Playgroud)

如果是java 8,则打印52,如果是java 11,则打印55。有了这个,您可以进行简单的比较,而不必处理版本字符串解析。


Eug*_*ota 5

我编写了一个bash函数,该函数应适用于JDK 9和JDK 10。

#!/bin/bash

# returns the JDK version.
# 8 for 1.8.0_nn, 9 for 9-ea etc, and "no_java" for undetected
jdk_version() {
  local result
  local java_cmd
  if [[ -n $(type -p java) ]]
  then
    java_cmd=java
  elif [[ (-n "$JAVA_HOME") && (-x "$JAVA_HOME/bin/java") ]]
  then
    java_cmd="$JAVA_HOME/bin/java"
  fi
  local IFS=$'\n'
  # remove \r for Cygwin
  local lines=$("$java_cmd" -Xms32M -Xmx32M -version 2>&1 | tr '\r' '\n')
  if [[ -z $java_cmd ]]
  then
    result=no_java
  else
    for line in $lines; do
      if [[ (-z $result) && ($line = *"version \""*) ]]
      then
        local ver=$(echo $line | sed -e 's/.*version "\(.*\)"\(.*\)/\1/; 1q')
        # on macOS, sed doesn't support '?'
        if [[ $ver = "1."* ]]
        then
          result=$(echo $ver | sed -e 's/1\.\([0-9]*\)\(.*\)/\1/; 1q')
        else
          result=$(echo $ver | sed -e 's/\([0-9]*\)\(.*\)/\1/; 1q')
        fi
      fi
    done
  fi
  echo "$result"
}

v="$(jdk_version)"
echo $v
Run Code Online (Sandbox Code Playgroud)

8对于Java 8("1.8.0_151"等)和9Java 9("9-Debian"等),这将返回,这将使进行进一步的比较更加容易。


Seb*_*hke 5

仅使用 grep 和 Perl 风格的正则表达式来确定 Java 版本可以如下完成:

java -version 2>&1 | grep -oP 'version "?(1\.)?\K\d+'
Run Code Online (Sandbox Code Playgroud)

这将打印 Java 9 或更高版本的主要版本以及低于 9 的版本的次要版本,例如8Java1.811Java 11.0.4

它可以这样使用:

JAVA_MAJOR_VERSION=$(java -version 2>&1 | grep -oP 'version "?(1\.)?\K\d+' || true)
if [[ $JAVA_MAJOR_VERSION -lt 8 ]]; then
  echo "Java 8 or higher is required!"
  exit 1
fi
Run Code Online (Sandbox Code Playgroud)

添加它|| true是为了防止脚本在未安装 Java 且set -e启用了 Shell 选项的情况下中止。