如何用Python的subprocess与Popen执行带插值参数的Java命令
我在Windows上尝试从Python中运行一个Java命令,使用的是subprocess和Popen。
首先,我定义了两个字符串:
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\\"
然后我尝试像下面这样使用subprocess:
subprocess.Open([java_string], cwd=working_dir)
结果出现了一个错误:
“FileNotFoundError: [WinError 2] 系统找不到指定的文件”
我把长长的java_string修改了一下,去掉了java命令,变成这样:
java_string = '-Xmx1024M -classpath .;./db2jcc.jar;./RetainSdi.zip;./jviews-chart.jar;./jviews-framework.jar l2stats CRF1426 > ' + datetime.date.today().strftime("%d/%m/%Y") + '.html'
然后我像这样调用Popen:
subprocess.Popen(['java', java_string], cwd=working_dir)
结果出现了:
无效的最大堆大小:-Xmx1024M -classpath .;./db2jcc.jar;./RetainSdi.zip;./jviews-chart.jar;./jviews-framework.jar l2stats CRF1426 > 21/04/2014.html 错误:无法创建Java虚拟机。
这至少是一个Java错误(所以它能在%PATH%中找到Java执行文件,但可能是因为Java把整个字符串当作一个参数看待?我也不太清楚。
这里的正确格式是什么?任何帮助都非常感谢!
1 个回答
3
你可能需要把参数分成一个列表,就像文档中提到的那样:
除非另有说明,建议将参数作为一个序列传递。
所以,不要这样写:
subprocess.Popen(['java', '-Xmx1024M -classpath . com.foo.Bar']
# Error (Invalid maximum heap size)
而是要这样:
subprocess.Popen(['java', '-Xmx1024M', '-classpath', '.', 'com.foo.Bar']
# OK
另外,关于Windows的特定情况,可以参考转换参数序列的规则。
更新:如果你需要使用一些shell的功能,比如用>
将输出重定向到文件,那么你需要加上shell=True
这个参数,比如:
subprocess.Popen('echo foo > deleteme.txt', shell=True)
或者按照J. F. Sebastian的评论中描述的那样,指定一个stdout
参数(为了方便,这里复制过来):
subprocess.call(['echo', 'foo'], stdout=open('deleteme.txt', 'wb'))
文档中有一点需要注意:
如果将shell=True与不可信的输入结合使用,可能会带来安全隐患。