Correct way to check Java version from BASH script

JavaBashVersionDependency Management

Java Problem Overview


How can I check whether Java is available (in the PATH or via JAVA_HOME) from a bash script and make sure the version is at least 1.5?

Java Solutions


Solution 1 - Java

Perhaps something like:

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

Solution 2 - Java

You can obtain java version via:

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

it will give you 16 for java like 1.6.0_13, 15 for version like 1.5.0_17 and 110 for openjdk 11.0.6 2020-01-14 LTS.

So you can easily compare it in shell:

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

UPDATE: This code should work fine with openjdk and JAVA_TOOL_OPTIONS as mentioned in comments.

Solution 3 - Java

The answers above work correctly only for specific Java versions (usually for the ones before Java 9 or for the ones after Java 8.

I wrote a simple one liner that will return an integer for Java versions 6 through 11 (and possibly all future versions, until they change it again!).

It basically drops the "1." at the beginning of the version number, if it exists, and then considers only the first number before the next ".".

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

Solution 4 - Java

You can issue java -version and read & parse the output

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

Solution 5 - Java

I wrote a bash function that should work for JDK 9 and 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

This returns 8 for Java 8 ("1.8.0_151" etc), and 9 for Java 9 ("9-Debian" etc), which should make it easier to do the further comparison.

Solution 6 - Java

You could also compare the jdk class version number with javap:

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

If its java 8, this will print 52, and 55 for java 11. With this you can make a simple comparison and you don't have to deal with the version string parsing.

Solution 7 - Java

A combination of different answers:

JAVA_VER=$(java -version 2>&1 | grep -i version | sed 's/.*version ".*\.\(.*\)\..*"/\1/; 1q')
  • Returns 7 for Java 7 and 8 for Java 8
  • Works with OpenJDK and with Oracle JDK
  • Works even if the JAVA_TOOL_OPTIONS is set

Solution 8 - Java

  1. in TERMINAL
java -version |& grep 'version' |& awk -F\" '{ split($2,a,"."); print a[1]"."a[2]}'
  1. in 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

Works in SUN and Linux

Solution 9 - Java

Determining the Java version only using grep with Perl-style regex can be done like this:

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

This will print the major version for Java 9 or higher and the minor version for versions lower than 9, for example 8 for Java 1.8 and 11 for Java 11.0.4.

It can be used like this:

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

The || true was added to prevent the script from aborting in case Java is not installed and the Shell option set -e was enabled.

Solution 10 - Java

The method I ended up using is:

# 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

It will work correctly even if JAVA_TOOL_OPTIONS is set to something due to filtering done by grep.

Solution 11 - Java

Another way is: A file called release is located in $JAVA_HOME. On Java 15 (Debian) it has as content:

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

So you see JAVA_VERSION, which contains the version number.

For example,

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

sets major to the value 15 (=Major version number), which you can use further.

It's a really simple solution.

Solution 12 - Java

I know this is a very old thread but this will still be of help to others.

To know whether you're running Java 5, 6 or 7, firstly type java -version.

There will be a line in your output that looks similar to this: java version "1.7.0_55"

Then you use this table for converting the 'jargon' result to the version number.

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

Information taken from a page on the Oracle site
http://www.oracle.com/technetwork/java/javase/7u55-relnotes-2177812.html

Solution 13 - Java

I had a similar problem, I wanted to check which version of java was installed to perform two types of application launches. The following code has solved my problem

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

source

I hope to be proved helpful

Solution 14 - Java

There is a nice portable bash function for this here: 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"
}

Solution 15 - Java

Using bashj, an extended bash version (https://sourceforge.net/projects/bashj/), you get a rather compact solution:

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

The answer is provided by an integrated JVM (in ~0.017'' execution time for the script , and ~0.004'' for the call itself).

Solution 16 - Java

I found the following works rather well. It is a combination of the answers from Michał Šrajer and jmj

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

I have openJDK 13 installed and without the awk command the first answer printed: 130 2020-01-14. Thus, adding awk '{ print $1 }' provides me with just the version.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAaron DigullaView Question on Stackoverflow
Solution 1 - Javaglenn jackmanView Answer on Stackoverflow
Solution 2 - JavaMichał ŠrajerView Answer on Stackoverflow
Solution 3 - JavadvlcubeView Answer on Stackoverflow
Solution 4 - JavajmjView Answer on Stackoverflow
Solution 5 - JavaEugene YokotaView Answer on Stackoverflow
Solution 6 - JavazhujikView Answer on Stackoverflow
Solution 7 - JavaManu D.View Answer on Stackoverflow
Solution 8 - JavaDavid Ben DavidView Answer on Stackoverflow
Solution 9 - JavaSeb TView Answer on Stackoverflow
Solution 10 - JavaJinesh ChoksiView Answer on Stackoverflow
Solution 11 - JavaJCWasmx86View Answer on Stackoverflow
Solution 12 - JavaRichardView Answer on Stackoverflow
Solution 13 - JavavincenzopalazzoView Answer on Stackoverflow
Solution 14 - JavaMatt RView Answer on Stackoverflow
Solution 15 - JavaFilView Answer on Stackoverflow
Solution 16 - JavaPaul StonerView Answer on Stackoverflow