如何正确重定向子流程的输出?

时间:2012-12-22 04:12:57

标签: python python-interactive

我正在为Windows做一个简单的shell替换shellpy(用于学习目的)。我显然希望shell独立于Windows CMD,因此我将所有输出重定向到StringIO对象。到目前为止它运作良好。

但是我在我的小shell中运行Python交互式解释器时遇到了一个问题。显然,交互式解释器会将所有内容写入 stderr ,但打印输出除外,它会写入 stdout 。用我的方法,我得到这样的输出:

shellpy - shellpy $ python
Python 2.7.3 (default, ...) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print "Hello, world!"
H>e>l>l o, world!

>>>

我无法理解这一点。我理解代码的方式是;每当子进程'stdout或stderr写入一个字节的数据时,它就被重定向到我的shell中的相应打印功能。那么,为什么这两者重叠呢?当然,Python解释器不会同时写入两个文件描述符?我的做法有缺陷吗?如果是这样,应该如何重定向子进程的输出?

注意非常很难在问题标题中描述我的问题,如果您能想到更好的事情,请随时编辑它。


此代码启动子流程:

child = subprocess.Popen(
    [command] + args,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

# Redirect the child's output to the shell.
redirect_pipe_output(child.stdout, self.print_text)
redirect_pipe_output(child.stderr, self.print_error)

# Wait for the child to finish.
child.wait()

这是重定向功能,它利用一个线程连续轮询子输出:

def redirect_pipe_output(fileobject, fn):
    """Creates a new thread and continuously tries to read from the input file
    object. When data is read from the file object, `fn` is called with that
    data."""

    def work():
        try:
            while True:
                fn(fileobject.read(1))
        except ValueError:
            pass

    t = threading.Thread(target=work)
    t.daemon = True
    t.start()

函数self.print_textself.print_error目前只是sys.stdout.write的包装。

0 个答案:

没有答案