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

问题描述 投票:0回答:18

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

java bash version dependency-management
18个回答
101
投票

也许是这样的:

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

53
投票

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

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

它将为您提供

16
(适用于 Java,如
1.6.0_13
)、
15
(适用于
1.5.0_17
等版本)和 110(适用于
openjdk 11.0.6 2020-01-14 LTS
)。

这样你就可以轻松地在 shell 中进行比较:

[ "$JAVA_VER" -ge 15 ] && echo "ok, java is 1.5 or newer" || echo "it's too old..."

更新: 这段代码应该可以与 openjdk 和 JAVA_TOOL_OPTIONS 一起正常工作,如评论中所述。


28
投票

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

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

它基本上删除了“1”。在版本号的开头(如果存在),然后仅考虑下一个“.”之前的第一个数字。

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


16
投票

您可以发出

java -version
并读取并解析输出

java -version 2>&1 >/dev/null | grep 'java version' | awk '{print $3}'

10
投票

您还可以通过

javap
来比较jdk类版本号:

javap -verbose java.lang.String | grep "major version" | cut -d " " -f5

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


8
投票

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

#!/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

这对于 Java 8(

8
等)返回
"1.8.0_151"
,对于 Java 9(
9
等)返回
"9-Debian"
,这应该可以更轻松地进行进一步比较。


5
投票

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

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

这将打印 Java 9 或更高版本的主要版本和低于 9 的版本的次要版本,例如

8
表示 Java
1.8
11
表示 Java
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

添加

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


4
投票

不同答案的组合:

JAVA_VER=$(java -version 2>&1 | grep -i version | sed 's/.*version ".*\.\(.*\)\..*"/\1/; 1q')
  • 对于 Java 7 返回
    7
    ,对于 Java 8
    返回 
    8
  • 与 OpenJDK 和 Oracle JDK 配合使用
  • 即使设置了 JAVA_TOOL_OPTIONS 也可以工作

3
投票
  1. 在航站楼
java -version |& grep 'version' |& awk -F\" '{ split($2,a,"."); print a[1]"."a[2]}'
  1. 在 BASH 中
#!/bin/bash


echo `java -version 2>&1 | grep 'version' 2>&1 | awk -F\" '{ split($2,a,"."); print a[1]"."a[2]}'`
jver=`java -version 2>&1 | grep 'version' 2>&1 | awk -F\" '{ split($2,a,"."); print a[1]"."a[2]}'`

if [[ $jver == "1.8" ]]; then                
     echo $jver is java 8
else
     echo $jver is java 11
fi

适用于 SUN 和 Linux


2
投票

我最终使用的方法是:

# Work out the JAVA version we are working with:
JAVA_VER_MAJOR=""
JAVA_VER_MINOR=""
JAVA_VER_BUILD=""

# Based on: http://stackoverflow.com/a/32026447
for token in $(java -version 2>&1 | grep -i version)
do
    if [[ $token =~ \"([[:digit:]])\.([[:digit:]])\.(.*)\" ]]
    then
        JAVA_VER_MAJOR=${BASH_REMATCH[1]}
        JAVA_VER_MINOR=${BASH_REMATCH[2]}
        JAVA_VER_BUILD=${BASH_REMATCH[3]}
        break
    fi
done

即使 JAVA_TOOL_OPTIONS 由于 grep 完成的过滤而设置为某些值,它也能正常工作。


2
投票

另一种方法是: 名为

release
的文件位于
$JAVA_HOME
中。 在 Java 15 (Debian) 上它的内容是:

IMPLEMENTOR="Debian"
JAVA_VERSION="15.0.1"
JAVA_VERSION_DATE="2020-10-20"
MODULES="java.base java.compiler java.datatransfer java.xml java.prefs java.desktop java.instrument java.logging java.management java.security.sasl java.naming java.rmi java.management.rmi java.net.http java.scripting java.security.jgss java.transaction.xa java.sql java.sql.rowset java.xml.crypto java.se java.smartcardio jdk.accessibility jdk.internal.vm.ci jdk.management jdk.unsupported jdk.internal.vm.compiler jdk.aot jdk.internal.jvmstat jdk.attach jdk.charsets jdk.compiler jdk.crypto.ec jdk.crypto.cryptoki jdk.dynalink jdk.internal.ed jdk.editpad jdk.hotspot.agent jdk.httpserver jdk.incubator.foreign jdk.internal.opt jdk.jdeps jdk.jlink jdk.incubator.jpackage jdk.internal.le jdk.internal.vm.compiler.management jdk.jartool jdk.javadoc jdk.jcmd jdk.management.agent jdk.jconsole jdk.jdwp.agent jdk.jdi jdk.jfr jdk.jshell jdk.jsobject jdk.jstatd jdk.localedata jdk.management.jfr jdk.naming.dns jdk.naming.rmi jdk.net jdk.nio.mapmode jdk.sctp jdk.security.auth jdk.security.jgss jdk.unsupported.desktop jdk.xml.dom jdk.zipfs"
OS_ARCH="x86_64"
OS_NAME="Linux"
SOURCE=""

所以你会看到

JAVA_VERSION
,其中包含版本号。

例如,

major=$(echo $JAVA_VERSION | cut -d. -f1)

major
设置为值 15(=主版本号),您可以进一步使用它。

这是一个非常简单的解决方案。


2
投票

获取java版本字符串,使用Bash内置的解析功能:

#!/usr/bin/env bash

java_cmd=${1:-java}

# Captures version string between double-quotes
IFS='"' read -r _ java_version_string _ < <("${java_cmd}" -version 2>&1)

# Splits version string at dots and (underscore for patch number)
IFS='._' read -r \
  java_version_major \
  java_version_minor \
  java_version_build \
  java_version_patch \
  <<<"$java_version_string"

# Debug demo output
declare -p java_version_major java_version_minor java_version_build \
  java_version_patch

示例

系统默认Java 17:

declare -- java_version_major="17"
declare -- java_version_minor="0"
declare -- java_version_build="3"
declare -- java_version_patch=""

作为参数提供的特定 Java 8 路径:

declare -- java_version_major="1"
declare -- java_version_minor="8"
declare -- java_version_build="0"
declare -- java_version_patch="352"

1
投票

我有一个类似的问题,我想检查安装了哪个版本的java来执行两种类型的应用程序启动。 下面的代码解决了我的问题

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"
}

_java="$(jdk_version)"
echo $_java

if [[ "$_java" > "$8" ]]; then
       echo version is more than 8

else
  echo version is less than 8

fi

来源

我希望对您有所帮助


1
投票

这里有一个很好的便携式 bash 函数:http://eed3si9n.com/detecting-java-version-bash

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"
}

0
投票

我知道这是一个非常古老的线程,但这仍然对其他人有帮助。

要了解您运行的是 Java 5、6 还是 7,请首先输入

java -version

输出中会有一行看起来与此类似:java version "1.7.0_55"

然后使用此表将“行话”结果转换为版本号。

1.7.0_55 是 Java 7
1.6.0_75 是 Java 6
1.5.0_65 是 Java 5

取自 Oracle 网站页面的信息
http://www.oracle.com/technetwork/java/javase/7u55-relnotes-2177812.html


0
投票

使用bashj,一个扩展的bash版本(https://sourceforge.net/projects/bashj/),你会得到一个相当紧凑的解决方案:

#!/usr/bin/bashj
echo System.getProperty("java.runtime.version")

答案由集成的 JVM 提供(脚本的执行时间约为 0.017 英寸,调用本身的执行时间约为 0.004 英寸)。


0
投票

我发现以下作品相当不错。它是 Michał Šrajerjmj

的答案的组合

version=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*"/\1\2/p;' | awk '{ print $1 }')
.

我安装了 openJDK 13,如果没有

awk
命令,第一个答案会打印:
130 2020-01-14
。因此,添加
awk '{ print $1 }'
只为我提供了版本。


0
投票

这个问题仍然相关,所以发布我的答案。

通过使用内置的 Bash 变量扩展并避免创建多个子 shell,使用稍微复杂的方式

line=$(java -version 2>&1 | head -1) && echo ${${${line#*\"}#1.}%%.*}

可以将其捕获到如下变量中,以便在脚本中进行进一步检查

version=$(line=$(java -version 2>&1 | head -1) && echo ${${${line#*\"}#1.}%%.*})
© www.soinside.com 2019 - 2024. All rights reserved.