我有一个名为pregeocode的Windows应用程序(我们缺少源代码),这个程序基本上将地理编码写入输入文件。除非出现错误,否则该程序实际上不会向控制台写入任何内容。这个程序通常从一个小的Python程序调用(它处理参数等,并进行所有有趣的预处理)。
我们通过查看输出文件是否实际创建来检查它是否失败(无论如何,它总是返回0)。但是当它失败时,子进程显示没有任何内容打印到stderr或stdout。 (它成功地处理了大约一百个左右,只有一个是坏的,但我希望能够看到导致错误的原因)
小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())
输出:
('', '')
但是如果我通过cmd使用相同的参数手动运行程序,我得到输出:
45 IMAGE_EXTENT_TOO_SMALL
(有大约60多个不同的错误消息,45表示错误号)
使用shell = True参数不会改变任何内容,也无法在线找到有关此问题的任何内容。实际的exe是很久以前在内部制作的东西,我们缺少它的源代码,所以我看不出它是如何打印出来的。
那么为什么子进程实际上不能捕获stdout或stderr?
修改的
os.system(" ".join(argslist))
正确打印错误消息:
45 IMAGE_EXTENT_TOO_SMALL
编辑2
原来应用程序使用ERDAS的工具包。他们的工具包将所有stdout / stderr重定向到他们的日志记录子系统。然后,日志记录子系统通过“CON”重写它。
答案 0 :(得分:5)
由于错误消息确实没有出现在stdout
或stderr
上,我最好的猜测是该程序正在使用Windows等同于打开/dev/tty
,无论是什么。在Unix中,您可以小心使用pty.openpty
来拦截它,但据我所知,Python中不支持类似Windows的特定技巧。您可以尝试使用Expect for Windows。
答案 1 :(得分:0)
您使用的是python 2.5还是2.6的早期版本? 你可以尝试这个subprocess.check_output与stderr重定向到stdout:
out_err = subprocess.check_output(argslist, stderr=subprocess.STDOUT)
如果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()