You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获Python子进程的交错stdin与stdout输出?

还原Python子进程的交互式输入输出效果

问题场景

我正在开发一个自动批改学生Python脚本的工具,学生提交的脚本会用input()获取用户输入,示例如下:

name = input('Enter your name: ')
print(f'Hello {name}!')

用subprocess.run()测试时,代码如下:

import subprocess

run_cmd = 'python student_script.py'
test_input = 'Bob'

p = subprocess.run(run_cmd.split(), input=test_input, capture_output=True, text=True)

此时p.stdout捕获到的内容是:

'Enter your name: Hello Bob!\n'

但我需要还原命令行的交互效果,得到如下格式的输出:

'Enter your name: Bob\nHello Bob!\n'

由于学生脚本的提示和输出不固定,无法手动插入测试输入到捕获的stdout中,需要可靠的方法捕获交错的stdin与stdout。

解决方案

subprocess.run()的input参数是通过管道传递输入,这种环境下input()不会回显输入内容,所以无法捕获到输入的回显。要实现需求,需要用**伪终端(pty)**模拟真实的终端环境,让input()自动回显输入内容。

代码实现

import pty
import os
import subprocess

def capture_interactive_session(cmd, input_str):
    # 创建伪终端主从设备
    master_fd, slave_fd = pty.openpty()
    
    # 启动子进程,将标准IO绑定到伪终端
    proc = subprocess.Popen(
        cmd,
        stdin=slave_fd,
        stdout=slave_fd,
        stderr=slave_fd,
        text=False  # 先以字节流处理,避免编码问题
    )
    os.close(slave_fd)  # 关闭子进程端的伪终端
    
    # 发送输入(需添加换行符模拟回车)
    os.write(master_fd, (input_str + '\n').encode())
    
    # 读取终端输出
    output_chunks = []
    while True:
        try:
            chunk = os.read(master_fd, 1024)
            if not chunk:
                break
            output_chunks.append(chunk.decode())
        except OSError:
            break  # 子进程结束后读取会抛出异常
    
    proc.wait()
    os.close(master_fd)
    
    return ''.join(output_chunks)

# 使用示例
if __name__ == '__main__':
    test_cmd = ['python', 'student_script.py']
    test_input = 'Bob'
    interactive_output = capture_interactive_session(test_cmd, test_input)
    print(repr(interactive_output))
    # 输出:'Enter your name: Bob\nHello Bob!\n'

原理说明

伪终端会模拟真实的命令行终端环境,当input()在终端环境中运行时,系统会自动回显用户输入的内容。通过将子进程的标准IO绑定到伪终端,我们就能捕获到完整的交互流程:提示信息 → 输入回显 → 脚本输出,完美还原命令行的交互效果。

内容的提问来源于stack exchange,提问作者Bob Loblaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:01:28