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

Python中重定向控制台输出到文件后发送邮件遇文件截断问题求助

解决控制台输出文件截断的问题

看起来你遇到的问题主要来自两个方面:原程序的输出缓冲没有真正写入磁盘,以及读取文件时的指针位置错误。咱们一步步来解决:

1. 先解决原程序的输出缓冲问题

当你用python my_app.py > console.txt重定向输出时,Python的stdout默认是块缓冲(只有当缓冲区满了或者程序退出时才会写入磁盘),而不是行缓冲(终端环境下才默认行缓冲)。这就导致即使你在读取时做了flush和fsync,原程序的输出可能还留在缓冲区里没写到磁盘。

你可以用以下方法强制原程序实时输出:

  • 运行时添加-u参数:直接用python -u my_app.py > console.txt启动程序,-u参数会让stdout和stderr变成无缓冲(或行缓冲),输出会立即写入磁盘。
  • 修改my_app.py内部刷新缓冲:在原程序中,每次输出后手动调用sys.stdout.flush();或者在程序开头设置sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', buffering=1)(Python3,行缓冲),确保输出实时写入。
  • 用stdbuf命令强制Shell行缓冲:如果不能修改原程序或Python参数,可通过Shell工具强制缓冲模式:stdbuf -oL python my_app.py > console.txt,-oL表示将stdout设为行缓冲。

2. 修正读取文件时的指针错误

看你的代码,打开文件后先执行了print(attachment.readline(-20)),这会把文件指针移动到该行的末尾,之后再调用attachment.read()只能读取指针之后的内容,前面的部分就被漏掉了,这也是附件内容截断的一个关键原因。

修正方法:

  • 如果只是测试读取,可以删掉那行测试代码;
  • 如果需要保留测试,在读取完整内容前把指针移回文件开头:
with open(filename, "r") as attachment:
    # 测试读取
    print(attachment.readline(-20))
    # 移回文件开头
    attachment.seek(0)
    # 读取完整内容
    part.set_payload(attachment.read())

另外,读取文件时不需要r+模式(读写模式),用只读r模式就足够了,避免不必要的权限问题;而且buffering=1在只读模式下意义不大,直接默认即可。

3. 确保读取前彻底刷新原程序的输出

如果你是在同一个脚本里既运行my_app.py又读取文件,那要确保原程序的子进程已经完成输出并刷新。比如用subprocess模块调用原程序,等待子进程结束后再读取文件:

import subprocess
subprocess.run(["python", "-u", "my_app.py"], stdout=open("console.txt", "w"))
# 此时子进程已结束,文件内容完整
with open("console.txt", "r") as f:
    full_content = f.read()

这样组合下来,应该就能拿到完整的console.txt内容作为邮件附件了。

内容的提问来源于stack exchange,提问作者Dmitri K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:32:52