我有一个执行系统调用的Python脚本(该调用实际上是一个java
程序)。
我正在使用Popen.communicate()
尝试来捕获stdout
和stderr
。但是,它仅适用于某些Java
应用程序(其中,我调用的所有java
应用程序在直接在shell中执行时会向屏幕显示内容。)
我使用的代码如下:
# Perform the java call
try:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except OSError as e:
error_msg = ' Error reading file while executing system command: {0}'.format(e.message)
except ValueError as e:
error_msg = ' Error in arugments while executing system command: {0}'.format(e.message)
else:
# Display the results in real time
for line in iter(p.stdout.readline, ''):
sys.stdout.write(line)
# Grab the stdout and stderr from the process.
output, err = p.communicate()
finally:
# Check to see if an internal error occurred. If not, flip the flag
if not err and not error_msg:
java_completed = True
else:
java_completed = False
在某些情况下,行sys.stdout.write(line)
永远不会被调用,而在其他情况下则是。
有没有人有这方面的经验?
答案 0 :(得分:1)
我注意到的第一件事是你从进程标准输出中读取所有内容,然后尝试communicate
之后:你已经读过管道中的所有内容,所以{{{ 1}}来自output
的结果将始终为空。
但这并不能解释为什么有时p.communicate()
没有被调用。
要记住的一件事是,有多种方法可以在控制台中显示内容(即在命令窗口中)。打印到流程标准输出流只是一种方式,这是您使用上述代码捕获的方式。如果我从Java时代开始回忆,有些类型的sys.stdout.write
类有时用于向控制台显示,这可能不会使用stdout。此外,高级控制台显示库(例如Console
)通常不会写入stdout,它们会直接与控制台对象进行交互。我不知道如何或者是否可以从这些类型的流程中捕获输出,但如果可能的话,它可能是非常特定于系统的。