如何用Python的subprocess与Popen执行带插值参数的Java命令

0 投票
1 回答
2307 浏览
提问于 2025-04-18 03:39

我在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与不可信的输入结合使用,可能会带来安全隐患。

撰写回答