最可靠方法是在命令中手动重定向输出:python train.py > log.txt 覆盖写入,>> 追加,> log.txt 2>&1 合并错误;VSCode 终端本身不保存输出,改设置或用调试控制台均无效。

终端命令运行时直接加 >> 或 2>&1 最可靠
VSCode 终端本身不保存输出,关掉就丢——这不是 bug,是设计。唯一零依赖、跨平台、立刻生效的办法,就是在运行命令时手动重定向。
-
python train.py > log.txt:覆盖写入标准输出,文件不存在会自动创建 -
python train.py >> log.txt:追加写入,适合多次运行累积日志 -
python train.py > log.txt 2>&1:把错误也合并进去,2>&1必须紧贴>,中间不能有空格(PowerShell 和 bash 都认这个写法) - 路径是相对的,基于你当前终端所在目录(通常是项目根目录),不是 VSCode 窗口路径
- 别用
cat log.txt查看——改用tail -f log.txt实时追踪新增内容
为什么改 launch.json 的 console 字段没用?
很多人以为把 launch.json 里 "console": "integratedTerminal" 换成 "externalTerminal" 或调大 terminal.integrated.scrollback 就能“保存输出”,其实不能。这些设置只影响输出显示位置或缓冲行数,不改变输出是否落盘。
-
scrollback默认是 1000 行,调到 5000 或 10000 可防翻页丢失,但内存占用会上升,尤其 WSL 下明显卡顿 - 调试控制台(
Debug Console)和集成终端(Integrated Terminal)是两套独立输出通道,print()走终端,logging.info()默认走调试控制台——它们互不共享缓冲区 - 就算开了自动保存(
files.autoSave: "afterDelay"),也只保存编辑器里的源码文件,跟运行输出无关
Python 脚本内用 logging.basicConfig 主动落盘
如果需要带时间戳、分级(INFO/WARN/ERROR)、或区分不同模块的日志,终端重定向就不够用了。这时候得在代码里主动接管输出流向。
- 加这三行就生效:
import logging<br>logging.basicConfig(filename="run.log", level=logging.INFO, format="%(asctime)s - %(message)s")
- 之后所有
logging.info("start")都自动写进文件,print()还是只打到终端,不会进日志 - 注意:文件路径是相对于脚本运行时的当前工作目录,不是脚本所在目录;想绝对路径就用
os.path.dirname(__file__)拼接 - 如果日志文件被其他进程占用(比如正用记事本打开),
basicConfig默认会静默失败,建议加filemode="a"显式声明追加模式
用 subprocess.run 在 Python 里捕获并保存输出
适合封装成自动化流程:比如跑完模型训练,自动存日志、发邮件、触发下一步。它绕过终端,直接从子进程管道读取原始字节流。
- 关键参数:
capture_output=True(等价于stdout=PIPE, stderr=PIPE),text=True(避免处理bytes) - 示例:
result = subprocess.run(["python", "train.py"], capture_output=True, text=True)<br>with open("train.log", "w") as f:<br> f.write(result.stdout)<br> f.write(result.stderr) - 如果子进程崩溃,
result.returncode != 0,但result.stderr仍包含报错信息,别漏读 - 注意:
subprocess启动的是新进程,它看不到父进程的环境变量(如os.environ),要用env=os.environ.copy()显式传递
真正容易被忽略的是:VSCode 的「调试控制台」和「集成终端」输出完全隔离,你在一个地方看到的内容,另一个地方不一定有。重定向只作用于终端启动的进程,对调试器启动的进程无效——除非你在 launch.json 里配 "console": "integratedTerminal" 并配合 shell 重定向。


















