简体   繁体   English

捕获未写入stdout的控制台输出,stderr?

[英]Capturing Console output that is not written to stdout,stderr?

I have an windows application called pregeocode (we lack source), this program basically writes geocoding to an input file. 我有一个名为pregeocode的Windows应用程序(我们缺少源代码),这个程序基本上将地理编码写入输入文件。 This program doesn't actually write anything to console unless there is an error. 除非出现错误,否则该程序实际上不会向控制台写入任何内容。 This program is generally called from a small Python program (it handles the arguments etc, and does all the fun preprocessing). 这个程序通常从一个小的Python程序调用(它处理参数等,并进行所有有趣的预处理)。

We check if it fails by seeing if the output file was actually created (it always returns 0, no matter what). 我们通过查看输出文件是否实际创建来检查它是否失败(无论如何,它总是返回0)。 However when it fails subprocess shows that nothing was printed to stderr or stdout. 但是当它失败时,子进程显示没有任何内容打印到stderr或stdout。 (It processes around a hundred or so successfully, with ussally only a single one being bad, but i would love to be able to see what causes the error) (它成功地处理了大约一百个,只有一个是坏的,但我希望能够看到导致错误的原因)

The small python script calls the application via subprocess.Popen: 小python脚本通过subprocess.Popen调用应用程序:

argslist = [r'C:\workspace\apps\pregeocode.exe', '-in', inputfilename, '-out', outputfilename, '-gcp', gcp_file]
p = subprocess.Popen(argslist, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
print str(p.communicate())

Gives the output of: 给出的输出:

('', '')

However if i run the program manually using the same arguments via cmd, i get the output of: 但是,如果我通过cmd使用相同的参数手动运行程序,我得到的输出:

45 IMAGE_EXTENT_TOO_SMALL

(There is around 60 odd different error messages, 45 indicates the error number) (有大约60多个不同的错误消息,45表示错误号)

Using the shell=True argument does not change anything, nor can i find anything online about this problem. 使用shell = True参数不会改变任何东西,我也无法在网上找到关于这个问题的任何内容。 The actual exe is something that was made in house a long time ago, and we lack the source code for it so i can't see how it prints out the messages. 实际的exe是很久以前在内部制作的东西,我们缺少它的源代码,所以我看不出它是如何打印出来的。

So why can't subprocess actually capture the stdout or stderr of this? 那么为什么子进程实际上不能捕获stdout或stderr呢?

EDIT 编辑

os.system(" ".join(argslist))

properly prints the error message: 正确打印错误消息:

45 IMAGE_EXTENT_TOO_SMALL

EDIT 2 编辑2

Turns out the application uses ERDAS's toolkit. 原来应用程序使用ERDAS的工具包。 Their toolkit redirects all stdout/stderr into their logging subsystem. 他们的工具包将所有stdout / stderr重定向到他们的日志记录子系统。 The logging subsystem then rewrites it via "CON". 然后,日志记录子系统通过“CON”重写它。

Since the error message really isn't coming in on either stdout nor stderr , my best guess is that the program is using Windows' equivalent of opening /dev/tty , whatever that is. 由于错误消息确实没有出现在stdoutstderr ,我最好的猜测是该程序正在使用Windows相当于打开/dev/tty ,无论是什么。 In Unix you could intercept that with careful use of pty.openpty but, as far as I know, there is no support for similar Windows-specific tricks in Python. 在Unix中你可以通过小心使用pty.openpty拦截它,但据我所知,在Python中不支持类似Windows的特定技巧。 You might try Expect for Windows instead. 您可以尝试使用Expect for Windows

Are you using python 2.5 or the early version of 2.6 ? 您使用的是python 2.5还是2.6的早期版本? Can you try this subprocess.check_output with stderr redirecting to stdout: 你可以尝试使用stderr重定向到stdout的subprocess.check_output:

out_err = subprocess.check_output(argslist, stderr=subprocess.STDOUT)

If out_err gets both the output and error, you'll probably need to redirect stdout and stderr to file objects and later read from those file objects (because windows do not have unix-like pipes): 如果out_err同时获得输出和错误,您可能需要将stdout和stderr重定向到文件对象,然后从这些文件对象中读取(因为窗口没有类似unix的管道):

fout = open('fout', 'w')
ferr = open('ferr', 'w')    
p = subprocess.Popen(argslist, stdout=fout, stderr=ferr)
p.wait()
fout.close()
ferr.close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM