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

为何fileinput.input无法作为subprocess.run的stdin?如何解决?

问题原因与解决方案

为什么fileinput.input作为subprocess.run的stdin会挂起?

fileinput.input()返回的是FileInput类实例,它仅模拟了文件对象的部分接口(如read()、readline()),并非真正的操作系统级文件描述符对象,也未实现fileno()方法。

当subprocess.run()接收这类无有效文件描述符的对象时,Python会启动后台线程读取该对象并写入子进程管道,但FileInput的内部迭代机制导致线程无法正确识别EOF(文件结束标记),子进程会一直等待输入,最终程序挂起。

如何传递多文件合并内容给子进程?

根据文件大小,可选择以下两种方案:

方案1:内存合并(适合小文件)

先将所有文件内容读入内存,再传递给子进程,实现简单:

import fileinput
import subprocess
import sys
from io import BytesIO

idle_path = sys.exec_prefix + "/bin/idle3"
paths = [idle_path]

# 读取所有文件内容到二进制内存对象
combined_content = BytesIO()
with fileinput.input(paths, mode='rb') as f:
    combined_content.write(f.read())
combined_content.seek(0)  # 重置读取指针到开头

subprocess.run(["cat"], stdin=combined_content)

方案2:流式传递(适合大文件)

通过管道流式写入内容,避免占用大量内存:

import fileinput
import subprocess
import sys

idle_path = sys.exec_prefix + "/bin/idle3"
paths = [idle_path]

# 启动子进程并创建输入管道
proc = subprocess.Popen(["cat"], stdin=subprocess.PIPE)

# 分块读取多文件内容并写入管道
with fileinput.input(paths, mode='rb') as f:
    for chunk in iter(lambda: f.read(4096), b''):
        proc.stdin.write(chunk)
proc.stdin.close()  # 关闭管道,告知子进程输入结束

# 等待子进程执行完成
proc.wait()

适配你的实际需求(cantools plot)

针对你需要调用cantools plot的场景,使用流式传递方案更适合日志文件:

import fileinput
import subprocess
import sys

# 配置实际参数
dbc_path = "/path/to/vehicle.dbc"
candump_paths = ["path/to/candump1.log", "path/to/candump2.log"]

# 启动cantools plot子进程
proc = subprocess.Popen(
    [sys.executable, "-m", "cantools", "plot", dbc_path],
    stdin=subprocess.PIPE
)

# 流式写入所有candump文件内容
with fileinput.input(candump_paths, mode='rb') as f:
    for chunk in iter(lambda: f.read(4096), b''):
        proc.stdin.write(chunk)
proc.stdin.close()
proc.wait()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:28:15