8

I need to get the java version number, for example "1.5", from python (or bash).

I would use:

os.system('java -version 2>&1 | grep "java version" | cut -d "\\\"" -f 2')

But that returns 1.5.0_30

It needs to be compatible if the number changes to "1.10" for example.

I would like to use cut or grep or even sed. It should be in one line.

5
  • 3
    "It needs to be compatible" - with what? What are you actually trying to achieve? "It should be in one line" - why? Commented Aug 4, 2015 at 11:20
  • compatible with newer java versions. And in one line to keep the code clean. Commented Aug 4, 2015 at 11:21
  • 2
    Why do you think that it will break with e.g. "1.10"? You're running a terminal command via os.system, I think "clean" has been and gone... Commented Aug 4, 2015 at 11:22
  • 1
    @jteichert one-liners aren't necessarily clean code. Commented Aug 4, 2015 at 11:23
  • @fedorqui i need just the major and minor version. The reason is, that this has to go into the build function of a waf script. That only accepts major.minor version (at least it didnt work just now when I used 1.5.0) bld(features = 'javac jar', compat = '1.5', ... ) Commented Aug 4, 2015 at 11:35

6 Answers 6

22

The Java runtime seems to send the version information to the stderr. You can get at this using Python's subprocess module:

>>> import subprocess
>>> version = subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)

>>> print version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) Client VM (build 24.79-b02, mixed mode)

You can get the version out with a regex:

>>> import re
>>> pattern = '\"(\d+\.\d+).*\"'

>>> print re.search(pattern, version).groups()[0]
1.7

If you are using a pre-2.7 version of Python, see this question: subprocess.check_output() doesn't seem to exist (Python 2.6.5)

Sign up to request clarification or add additional context in comments.

9 Comments

very nice one! I learnt a lot from it, better than my calling to external awk.
This is the right answer. Keep the subprocess as simple as possible (just get the output from java), and process the resulting string in Python.
thanks, one remark: subprocess only worked when I replaced check_output with check_call. I have python 2.6 installed.
@jteichert I've updated the answer with a link to a question about missing check_output, pre-2.7.
If you have set JAVA_TOOL_OPTIONS env variable then java will print the options before the actual result, which might break your regex later.
|
4

Considering an output like this:

$ java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

You can get the version number with awk like this:

$ java -version 2>&1 | awk -F[\"_] 'NR==1{print $2}'
1.8.0

Or, if you just want the first two .-separated digits:

$ java -version 2>&1 | awk -F[\"\.] -v OFS=. 'NR==1{print $2,$3}'
1.8

Here, awk sets the field separator to either " or _ (or .), so that the line is sliced in pieces. Then, it prints the 2nd field on the first line (indicated by NR==1). By setting OFS we indicate what is the output field separator, so that saying print $2, $3 prints the 2nd field followed by the 3rd one with a . in between.

To use it in Python you need to escape properly:

>>> os.system('java -version 2>&1 | awk -F[\\\"_] \'NR==1{print $2}\'')
1.8.0
>>> os.system('java -version 2>&1 | awk -F[\\\"\.] -v OFS=. \'NR==1{print $2,$3}\'')
1.8

4 Comments

You can't capture the child's output with os.system(), so this method is less practical than others.
@mhawke Not sure why child's output may be necessary here. Also, as I said below Peter Wood's answer, I also thing his answer is superior since it uses Python entirely.
Surely the child's output is necessary if you actually want to do anything with the version number obtained.
You really want to avoid os.system() and Awk here. The subprocess answer should be the accepted one.
1

You could let grep handle a regular expression:

java -version 2>&1 | grep -Eow '[0-9]+\.[0-9]+' | head -1

Comments

1

You can't capture the command's output with os.system(). Instead, use subprocess.check_output():

>>> import subprocess
>>> java_version = subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)
>>> java_version
'openjdk version "1.8.0_51"\nOpenJDK Runtime Environment (build 1.8.0_51-b16)\nOpenJDK 64-Bit Server VM (build 25.51-b03, mixed mode)\n'

Now that you can collect the command output, you can extract the version number using Python, rather than piping through other commands (which, incidentally, would require use of the less secure shell=True argument to check_output).

>>> version_number = java_version.splitlines()[0].split()[-1].strip('"')
>>> major, minor, _ = version_number.split('.')
>>> print 'Major: {}, Minor: {}'.format(major, minor)
Major: 1, Minor: 8

Comments

1

It's an old post, but if someone needs it:

import subprocess
import re

javaPath = 'C:/.../java.exe'

javaInfo = subprocess.check_output(javaPath + ' -version', shell=True, stderr=subprocess.STDOUT)
javaVersion = re.search(r'"[0-9\._]*"', javaInfo.decode().split("\r")[0]).group().replace('"', '')

print(javaVersion)

Comments

0

python

import os;

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

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

print xxx
1.8

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.