0

trying to run a java command from within python on Windows, using subprocess & Popen.

First I've defined two strings:

java_string = 'java -Xmx1024M -classpath .;./db2jcc.jar;./RetainSdi.zip;./jviews-chart.jar;./jviews-framework.jar l2stats CRF1426 > ' + datetime.date.today().strftime("%d/%m/%Y") + '.html'

working_dir = "C:\\Users\\IBM_ADMIN\\Desktop\\Weekly Report 2014\\"

then I tried to use subprocess as follows:

subprocess.Open([java_string], cwd=working_dir)

which results in a "FileNotFoundError: [WinError 2] The system cannot find the file specified"

I've edited the long java_string to not have the java command, like so:

java_string = '-Xmx1024M -classpath .;./db2jcc.jar;./RetainSdi.zip;./jviews-chart.jar;./jviews-framework.jar l2stats CRF1426 > ' + datetime.date.today().strftime("%d/%m/%Y") + '.html'

and then called Popen like so:

subprocess.Popen(['java', java_string], cwd=working_dir)

which results in a

Invalid maximum heap size: -Xmx1024M -classpath .;./db2jcc.jar;./RetainSdi.z ip;./jviews-chart.jar;./jviews-framework.jar l2stats CRF1426 > 21/04/2014.html Error: Could not create the Java Virtual Machine.

which is at least a java error (so it's finding the java exec. in the %PATH%, but has to do with java seeing the entire string as a single argument? I have no idea.

What is the correct formatting here? Any help much appreciated!

1 Answer 1

3

You probably need to split the arguments into a list, as described in the documentation:

Unless otherwise stated, it is recommended to pass args as a sequence.

So instead of:

subprocess.Popen(['java', '-Xmx1024M -classpath . com.foo.Bar']
# Error (Invalid maximum heap size)

use:

subprocess.Popen(['java', '-Xmx1024M', '-classpath', '.', 'com.foo.Bar']
# OK

See also the Windows-specific rules for converting an argument sequence.

Updated: If you need to use features of the shell, such as redirection to a file using >, then you need to include the shell=True argument, for example:

subprocess.Popen('echo foo > deleteme.txt', shell=True)

Or specify a stdout argument as described in the comment from J. F. Sebastian (copied here for convenience):

subprocess.call(['echo', 'foo'], stdout=open('deleteme.txt', 'wb'))

One note from the documentation:

Passing shell=True can be a security hazard if combined with untrusted input.

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

5 Comments

How do characters like the '>' fit into the argument list? Is it it's own argument? Thank you for the answers so far!
I have updated my answer with some examples of this.
Please, do not use a list argument and shell=True together. It has completely different meaning on POSIX systems. You could always use a string on Windows.
@user3434388: instead of > deleteme.txt, you could set stdout parameter e.g., subprocess.call(['echo', 'foo'], stdout=open('deleteme.txt', 'wb'))
Updated answer to only show the string/shell variant for Windows.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.