Python3.7环境下如何记录InteractiveConsole的stdin、stdout及stderr日志
问题根因
- 方法名拼写错误:自定义
StdIn类的tty判断方法名为istty,正确应为isatty,导致系统判定当前输入不是tty设备,自动禁用readline行编辑功能,方向键输入会直接输出原始转义字符。 - EOF逻辑缺失:自定义
get_input方法读到ctrl+d返回的空字符串时,没有抛出EOFError,导致InteractiveConsole无法触发退出逻辑。 - 父类未初始化:
StdIn继承TextIOWrapper但未调用父类初始化方法,Python3运行会直接报错。 - 绕过readline处理:直接重写
InteractiveConsole.raw_input绕开了系统原生的readline行编辑逻辑,导致历史命令查询、tab补全、方向键操作等功能全部失效。
Python3适配解决方案
import sys import code import atexit import readline # 日志对象,后续可替换为自研日志组件 logger = open("console_output.txt", "w", encoding="utf-8") def clean_up(): sys.stdout = sys.__stdout__ sys.stdin = sys.__stdin__ sys.stderr = sys.__stderr__ logger.write("end\n") logger.flush() logger.close() atexit.register(clean_up) # 标准输出/错误重定向类 class StdIOCopier: def __init__(self, original_stream, logger): self.original = original_stream self.logger = logger def write(self, s): res = self.original.write(s) self.original.flush() self.logger.write(s) self.logger.flush() return res def fileno(self): return self.original.fileno() def isatty(self): return self.original.isatty() @property def errors(self): return self.original.errors @property def encoding(self): return self.original.encoding def flush(self): self.original.flush() # 重定向输出和错误 sys.stdout = StdIOCopier(sys.__stdout__, logger) sys.stderr = StdIOCopier(sys.__stderr__, logger) # 包裹原生输入逻辑,确保输入完整记录 original_input = input def logged_input(prompt=""): try: line = original_input(prompt) logger.write(line + "\n") logger.flush() return line except EOFError: # 处理ctrl+d退出 logger.write("\n") raise # 初始化交互式控制台 console = code.InteractiveConsole(locals=dict(globals(), **locals())) console.raw_input = logged_input # 写入日志开头 logger.write("start\n") logger.flush() # 启动交互 console.interact(banner="自定义Python交互终端已启动")
功能验证
- 所有tty功能正常:方向键移动光标、上下键查询历史命令、tab补全都可正常使用
ctrl+d可正常退出交互式shell- 日志文件完整记录所有输入、输出、错误信息,无多余转义字符
- 可直接替换
logger对象的写入逻辑对接自研日志组件,无需修改其他核心代码
内容的提问来源于stack exchange,提问作者user46809
相关产品推荐
相关产品推荐

