1

shellpy と呼ばれる Windows 用の単純なシェルの代替品を作成しています (学習目的で)。明らかに、シェルを Windows CMD から独立させたいので、すべての出力を StringIO オブジェクトにリダイレクトしています。これまでのところ、かなりうまく機能しています。

しかし、小さなシェル内で Python インタラクティブ インタープリターを実行しているときに問題が発生しました。明らかに、対話型インタープリターは、 stdoutに書き込む印刷出力を除いて、すべてをstderrに書き込みます。私のアプローチでは、次のような出力が得られます。

シェルピー - shellpy $ python
Python 2.7.3 (デフォルト、...) [MSC v.1500 64 ビット (AMD64)] (win32)
詳細については、「ヘルプ」、「著作権」、「クレジット」、または「ライセンス」と入力してください。
>>> print "Hello, world!"
こんにちは、世界!

>>>

私はこれを理解することはできません。私のコードを理解する方法は次のとおりです。子プロセスの stdout または stderr によって 1 バイトのデータが書き込まれるたびに、シェルの適切な印刷機能にリダイレクトされます。では、なぜ両者が重なり合うのでしょうか。確かに、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