我从python调用一个java应用程序,如下所示:
proc = subprocess.Popen(
["java", "-jar", "application.jar", "-o", "/path/to/outfile", "/path/to/infile"])
当子进程在如上所述的后台静默运行时,这将按预期工作(应用程序生成文件,这些文件包含它们应该包含的内容)。在
然而,我希望一个进程被阻塞,另一个捕捉它的输出。在
因此,采用以下方法:
^{pr2}$这将失败(以前成功生成的文件为0字节)-即使Popen
参数完全相同。在
没有try ... except
和条件
proc = subprocess.Popen(
["java", "-jar", "application.jar", "-o", "/path/to/outfile", "/path/to/infile"],
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
print proc.communicate() #prints java exception
它仍然失败。print proc.communicate()
打印的异常是一个Java StringIndexOutOfBoundsException
,以防它产生差异。
删除对communicate()
的调用时,会使其再次按计划执行:
proc = subprocess.Popen(
["java", "-jar", "application.jar", "-o", "/path/to/outfile", "/path/to/infile"],
stderr=subprocess.PIPE,
stdout=subprocess.PIPE) # runs just fine
更多信息(编辑)
这个java应用程序是YUI Compressor,雅虎的CSS和JS压缩工具。在
如果它确实有助于揭示事实,那么从java到python的完整堆栈跟踪包含在上面第二个代码块的psterr
中:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.yahoo.platform.yui.compressor.Bootstrap.main(Bootstrap.java:21)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -860
at java.lang.AbstractStringBuilder.substring(AbstractStringBuilder.java:908)
at java.lang.StringBuffer.substring(StringBuffer.java:482)
at com.yahoo.platform.yui.compressor.CssCompressor.compress(CssCompressor.java:126)
at com.yahoo.platform.yui.compressor.YUICompressor.main(YUICompressor.java:211)
... 5 more
TL;DR
虽然我只是为了捕捉输出而调用communicate()
,但它也会以某种方式向子进程发送垃圾,使其失败。
为什么会这样?在
我假设这是因为java应用程序仍然从stdin
读取,而communicate()
发送它EOF
。
如何在不发送EOF
的情况下实现相同的功能?在
我可以让进程在后台静默运行,但我更喜欢一种解决方案,允许它阻塞,让我捕捉输出。
有没有解决这个障碍的方法?在
提前谢谢!在
目前没有回答
相关问题 更多 >
编程相关推荐