1

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

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

shellpy - shellpy $ python
Win32 上的 Python 2.7.3(默认,...)[MSC v.1500 64 位 (AMD64)]
输入“帮助”、“版权”、“信用”或“许可”以获取更多信息。
>>> 打印“你好,世界!”
H>e>l>lo,世界!

>>>

我无法理解这一点。我理解我的代码的方式是;每次子进程的 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.

4

0 回答 0