无法在 subprocess.run 中使用 fileinput.input 作为标准输入

问题描述 投票:0回答:1

我的印象是

fileinput.input([path_1, path2, ...])
基本上可以与
open(path_1)
互换,只是前者连接了所有给定文件的内容。但是,当将
fileinput.input
作为
stdin
传递给
subprocess.run
时,其行为会有所不同。也就是说,
subprocess.run
只是挂起并且根本不从文件中读取任何内容。

这是一个例子:

示例.py:

import fileinput
import subprocess
import sys

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

with fileinput.input(paths) as combined_file:
# with open(idle_path) as combined_file:
    subprocess.run(["cat"], stdin=combined_file)

调用上面的例子在控制台中使用

python example.py
未完成。

使用

open
而不是
fileinput.input
,它可以正常工作并按预期生成
/bin/idle3
的内容:

$ python example.py
#!/home/me/mambaforge/envs/testenv/bin/python3.12

from idlelib.pyshell import main
if __name__ == '__main__':
    main()

那里发生了什么事?如何将多个文件的组合内容通过管道传输到我想要与

subprocess.run
一起使用的任何命令?

我在 Python 3.12 上看到了这个,不确定它是否有什么区别。我实际上尝试运行的命令不是

cat
而是
subprocess.run([sys.executable, "-m", "cantools", "plot", "/path/to/vehicle.dbc"], stdin=combined_candumps)
。 (参见cantools文档)。在 shell 中运行整个过程并不是一个真正的选择,因为我想从 GUI 中获取一些参数并用 Python 编写。虽然 cantools 是用 Python 编写的,但它具有仅限 shell 的 API,并且没有记录的 Python 接口。这就是往返
subprocess.run
的原因。

python file-io subprocess
1个回答
0
投票

来自 https://docs.python.org/3/library/subprocess.html#subprocess.run ,部分,重点是我的:

stdin、stdout 和 stderr [...] 有效值为 [...] 现有文件对象 具有有效的文件描述符

fileinput.input
是一个Python对象,它不是文件描述符。

如何将多个文件的组合内容通过管道传输到我想要与 subprocess.run 一起使用的任何命令?

您将创建一个管道来创建文件描述符,异步写入管道并让进程读取它。一些未经测试的东西写在这里:

def cat(paths, file):
   with fileinput.input(paths) as combined_file:
      for line in combined_file:
         print(line, file=file)

r, w = os.pipe()
threading.Thread(target=lambda: cat(paths, os.fdopen(w))).start()
subprocess.run(["cat"], stdin=r)
© www.soinside.com 2019 - 2024. All rights reserved.