为何call()执行后后续代码无法运行?终端日志脚本执行异常
解决Python脚本内记录终端输入输出的问题
我明白你的问题了——你想用script命令完整记录脚本运行时的所有终端输入和输出,但直接在脚本开头调用script会导致程序卡住,因为script默认会启动一个交互式shell,你的Python代码得等这个shell手动退出后才会继续执行。下面给你两种可行的解决方案:
方法一:让script直接执行你的Python脚本
这个方法利用script的-c参数,让它直接运行你的业务代码,而不是启动交互式shell。我们可以在脚本开头判断是否已经处于script会话中,如果没有,就调用script来重新执行当前脚本:
import os import sys from subprocess import call # 检查是否已经在script记录会话中(通过环境变量标记) if 'SCRIPT_SESSION' not in os.environ: # 设置环境变量,标记已进入script会话 os.environ['SCRIPT_SESSION'] = '1' # 让script执行当前Python脚本,同时指定日志文件 cmd = f"{sys.executable} {' '.join(sys.argv)}" call(["script", "-c", cmd, "session.log"]) # 执行完script后退出原进程 sys.exit() # -------------------------- # 以下是你的业务代码 belong = raw_input("Random input getter no.1 ") take = raw_input("Input getter no.2") def ok(): print "OK" def place(): print "PLACE" def hope(): print "HOPE" if belong != 'mcr': ok() if take != 'mcrr': place() hope() print "random words" print "more words"
原理说明:
- 第一次运行脚本时,没有
SCRIPT_SESSION环境变量,会调用script -c "python your_script.py" session.log,让script启动一个新的会话来执行你的脚本。 - 第二次执行脚本(在
script会话内)时,因为环境变量存在,会跳过script调用部分,直接执行业务代码。 script会自动记录整个会话的输入和输出,执行完脚本后自动退出,不会卡住。
方法二:Python内部实现输入输出重定向(不依赖script命令)
如果你不想依赖外部的script工具,可以自己实现输入输出的重定向,同时把内容写入日志文件:
import sys class TerminalLogger: def __init__(self, log_file): self.terminal = sys.stdout self.log = open(log_file, 'a') def write(self, msg): # 同时输出到终端和日志文件 self.terminal.write(msg) self.log.write(msg) self.flush() def flush(self): self.terminal.flush() self.log.flush() class InputRecorder: def __init__(self, log_file): self.terminal = sys.stdin self.log = open(log_file, 'a') def readline(self): # 读取用户输入后,同时写入日志文件 line = self.terminal.readline() self.log.write(line) self.log.flush() return line # 替换默认的stdout和stdin sys.stdout = TerminalLogger('session.log') sys.stdin = InputRecorder('session.log') # -------------------------- # 以下是你的业务代码 belong = raw_input("Random input getter no.1 ") take = raw_input("Input getter no.2") def ok(): print "OK" def place(): print "PLACE" def hope(): print "HOPE" if belong != 'mcr': ok() if take != 'mcrr': place() hope() print "random words" print "more words"
原理说明:
- 我们自定义了
TerminalLogger和InputRecorder类,分别包装了系统的标准输出和输入。 - 所有的
print输出会同时显示在终端并写入日志文件,所有的用户输入也会被记录到日志中。 - 这种方法更灵活,不需要依赖外部工具,但无法捕获终端的控制字符(比如密码输入时的隐藏字符),适合普通的文本输入输出场景。
内容的提问来源于stack exchange,提问作者user7355384
相关产品推荐
相关产品推荐

