Reputation: 3662
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
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