通过子进程进行Python重定向的奇怪行为

时间:2017-09-24 05:40:01

标签: python subprocess lxml bottle

我有一个非常奇怪的错误,我无法解决。我已将代码最小化到最小量以重现问题:

from lxml import etree
xsd_prs = etree.XMLParser(remove_blank_text=True)
print "**", xsd_prs

我执行的命令如下:

cmd = 'python myprog.py -f myfile.xsd > out.txt 2>&1'

当我从命令行运行时,我得到了out.txt中的预期:

** <lxml.etree.XMLParser object at 0x10b0fd550>

但是,当我使用以下内容从基于Python / Bottle的Web应用程序中运行它时:

pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
pro.wait()

此处,etree.XMLParser()函数不返回任何内容。我只是在out.txt文件中获得以下内容:

**

我还应该提到我一直在使用相同的subprocess.Popen()方法来执行各种不同的命令,除了这个。 为什么没有输出对象的字符串表示?

我也使用Python的内置XML解析器尝试了同样的事情:

import xml.etree.ElementTree as ET
tree = ET.parse(fn)
doc = tree.getroot()
print "***", doc

从命令行运行时获得类似的结果:

*** <Element '{http://www.w3.org/2001/XMLSchema}schema' at 0x115675f90>

与从网络应用程序运行相比:

***

1 个答案:

答案 0 :(得分:0)

我终于弄清楚这里发生了什么,而且根本不明显。当我尝试写出xsd_prs对象时,会以某种方式破坏所有后续重定向。疯狂的是,如果我试图重定向对象,任何其他后续的print语句都不会重定向,所以看起来我的程序根本不起作用。删除print "**", xsd_prs后,可以重定向具有正确字符串表示的所有后续字符串。

我首先通过打印dir(xsd_prs)来发现这一点,它实际上输出了我可以在对象上调用的方法列表,这实际上证明了XMLParser()正在返回一个对象。

我还发现如果我在Python程序中创建了另一个输出文件,我可以编写对象的字符串表示,但不能通过重定向。

如果有人有任何链接解释为什么Python重定向以这种方式工作,我会感兴趣,如果你可以在下面的评论中发表或添加更详细的答案。