Danielle M.
Danielle M.

Reputation: 3662

How to execute a java command with interpolated arguments with Python's subprocess & Popen

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!

Upvotes: 0

Views: 2364

Answers (1)

DNA
DNA

Reputation: 42597

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.

Upvotes: 3

Related Questions