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

Windows下Python subprocess不遵循stdout追加模式问题及解决方案咨询

问题分析

这不是Python的bug,是Windows与类Unix系统底层文件模型的固有差异导致的现象:

  • Linux系统中O_APPEND是文件描述符关联的内核级属性,子进程继承文件描述符后属性依然生效,所有写入操作都会自动定位到文件末尾,不会出现覆盖或空洞。
  • Windows系统中C runtime的O_APPEND标记是进程内的用户态属性,不会随文件句柄继承传递给子进程。子进程拿到继承的文件句柄后,写入操作会使用自身维护的文件指针偏移,不会自动追加到文件末尾。
  • 你复现代码中父进程调用file.write_text('')会将文件截断为0长度,但子进程的文件指针还停留在原文件长度(11字节)的位置,子进程写入时就会在前面填充11个NUL字符,最终出现你看到的异常输出。
解决方案

方案1:子进程输出父进程追加(最稳妥,跨平台兼容)

不要在父进程打开文件传递给子进程,改为父进程捕获子进程的标准输出,再手动追加到目标文件,无需修改子进程代码也不需要区分操作系统:

import subprocess, time, pathlib, sys
print(f'Caller {sys.platform=} {sys.version=}')

pathlib.Path('sub.py').write_text("""import sys, time
time.sleep(1)
print(f'Callee {sys.stdout.buffer.mode=}')""")

file = pathlib.Path('dummy.txt')
file.write_text('Hello World')
# 捕获子进程输出
popen = subprocess.Popen([sys.executable, 'sub.py'], stdout=subprocess.PIPE, text=True)
stdout, _ = popen.communicate()
# 父进程手动追加到文件
with open(file, 'a') as f:
    f.write(stdout)
print(file.read_text())

方案2:Windows专属传递可继承追加句柄

如果必须在父进程打开文件传递给子进程,Windows下需要手动创建带FILE_APPEND_DATA权限的可继承句柄:

import subprocess, time, pathlib, sys
import win32file, win32con, msvcrt

print(f'Caller {sys.platform=} {sys.version=}')

pathlib.Path('sub.py').write_text("""import sys, time
time.sleep(1)
print(f'Callee {sys.stdout.buffer.mode=}')""")

file = pathlib.Path('dummy.txt')
file.write_text('Hello World')

# 创建支持追加的可继承Windows文件句柄
handle = win32file.CreateFileW(
    str(file),
    win32con.FILE_APPEND_DATA,
    win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
    None,
    win32con.OPEN_ALWAYS,
    win32con.FILE_ATTRIBUTE_NORMAL,
    None
)
# 转换为C runtime文件描述符
fd = msvcrt.open_osfhandle(handle, 0)
f = open(fd, 'a')
# 传递句柄时必须设置close_fds=False
popen = subprocess.Popen([sys.executable, 'sub.py'], stdout=f, close_fds=False)
file.write_text('')
time.sleep(2)
print(file.read_text())

内容的提问来源于stack exchange,提问作者Wolfgang Kuehn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:09:01