我正在为 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_text
和self.print_error
目前只是sys.stdout.write
.