communicate()导致子进程失败为什么?

2024-04-25 02:29:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我从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的情况下实现相同的功能?在

我可以让进程在后台静默运行,但我更喜欢一种解决方案,允许它阻塞,让我捕捉输出。
有没有解决这个障碍的方法?在

提前谢谢!在


Tags: topath应用程序langapplication进程procjava