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?
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
type
builtin. –
Octo IFS=. read major minor extra <<<"$version"; if (( major == 1 && minor > 5 )); ...
-- would have to check for invalid octal numbers like "08". –
Seifert type -p java
" won't work in "sh"; so, for portability, use #!/bin/bash
in the script, rather than #!/bin/sh
(though, it's possible that /bin/sh
isn't actually bourne shell, but rather a backward compatible variant) –
Grimace version1=$(echo "$version" | awk -F. '{printf("%03d%03d",$1,$2);}')
which will get you major and minor aligned with 3 digit for each, and then compare with if [ $version1 -ge 001008 ] ; then
–
Owensby IFS=. read major minor extra <<<$(java -version 2>&1 | awk -F '"' '/version/ {print $2}'); if [ $major -lt 1 -o $major -eq 1 -a $minor -le 7 ]; then JVM_EXTRA_OPTS="-Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1"; fi
–
Apportion You can obtain java version via:
JAVA_VER=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{sub("^$", "0", $2); print $1$2}')
it will give you 16
for java like 1.6.0_13
, 15
for version like 1.5.0_17
, 110
for openjdk 11.0.6 2020-01-14 LTS
and 210
for java version 21 2023-09-19 LTS
.
So you can easily compare it in shell:
[ "$JAVA_VER" -ge 15 ] && echo "ok" || echo "too old"
UPDATE:
This code should work fine with openjdk and JAVA_TOOL_OPTIONS
as mentioned in the comments.
sed 's/.*version "\(.*\)\.\(.*\)\..*"/\1\2/; 1q'
–
Gratitude 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
You can issue java -version
and read & parse the output
java -version 2>&1 >/dev/null | grep 'java version' | awk '{print $3}'
$PATH
before it calls locate
(which isn't always available)? –
Octo java -version 2>&1 >/dev/null | grep 'java version' | awk '{print $3}'
by the time –
Giorgia java -version 2>&1 | head -1 | cut -d '"' -f 2
–
Unwisdom 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.
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.
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.
A combination of different answers:
JAVA_VER=$(java -version 2>&1 | grep -i version | sed 's/.*version ".*\.\(.*\)\..*"/\1/; 1q')
- Returns
7
for Java 7 and8
for Java 8 - Works with OpenJDK and with Oracle JDK
- Works even if the JAVA_TOOL_OPTIONS is set
- in TERMINAL
java -version |& grep 'version' |& awk -F\" '{ split($2,a,"."); print a[1]"."a[2]}'
- 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
$(...)
instead of backticks. They are safer, support nesting, and easier to type on most keyboards/OSs. –
Octo 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.
if [[ $(java -version 2>&1 >/dev/null | grep 'java version' | awk '{print $3}') =~ \"([0-9])\.([0-9])\.([0-9])_(.*)\" ]]; then echo ${BASH_REMATCH[2]}; fi
–
Twist 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.
$JAVA_HOME
isn't defined. –
Octo Getting java version string, using Bash's built-in parsing capabilities:
#!/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
Examples
System default Java 17:
declare -- java_version_major="17"
declare -- java_version_minor="0"
declare -- java_version_build="3"
declare -- java_version_patch=""
Specific Java 8 path provided as argument:
declare -- java_version_major="1"
declare -- java_version_minor="8"
declare -- java_version_build="0"
declare -- java_version_patch="352"
-bash: java_version_major: command not found
for the line with the here string <<<
. –
Octo IFS="." read java_version_major java_version_minor java_version_build java_version_patch <<< "$java_version_string"
works for me. –
Octo 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
I hope to be proved helpful
sed
with BASH parameter expansion (gnu.org/software/bash/manual/html_node/…) using ${parameter/pattern/string}
–
Octo 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"
}
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
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).
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.
This question is still relevant so posting my answer.
Using slightly convoluted way by using built-in Bash variable expansions and avoiding creating multiple sub-shells
line=$(java -version 2>&1 | head -1) && echo ${${${line#*\"}#1.}%%.*}
Returns 8 for Java 1.8.0_312 and 17 for 17.0.6
This can be used in a script like below
#!/bin/bash
required=5
version=$(line=$(java -version 2>&1 | head -1) && echo ${${${line#*\"}#1.}%%.*})
[[ $version -ge $required ]] && echo "Java version OK" || echo "Java version too low"
You can get the process ID by using ps -ef | grep -v grep | grep java and then use jcmd process_id vm.version
One-liner to check for a minimum required Java version in bash:
(echo 'class a{public static void main(String[] a){}}' > a.java && java --source 17 a.java || a=$? ; (rm -f a.java ; exit $a))
The exitcode indicates if Java 17+ is available. Note that this requires a (temp) file a.java
.
© 2022 - 2024 — McMap. All rights reserved.