Python3如何在使用subprocess.run()时将二进制数据传递给stdin?

7
那么,如何使用stdin传递二进制数据给可执行命令,在使用subprocess.run()运行该命令时呢?
关于使用stdin将数据传递给外部可执行文件的方式,文档描述非常模糊。我在使用Python3的Linux机器上工作,我想调用dd of=/somefile.data bs=32(如果我正确理解man page,则从stdin获取输入),我有一个bytearray中的二进制数据,我想通过stdin将其传递给该命令,以便我不必将其写入临时文件并使用该文件作为输入来调用dd
我的要求很简单,只需将我在bytearray中拥有的数据传递给dd命令以写入磁盘。使用subprocess.run()和stdin实现这一点的正确方法是什么?
编辑:我的意思是像以下示例一样:
ba = bytearray(b"some bytes here")
#Run the dd command and pass the data from ba variable to its stdin

使用Popen时,您可以设置stdin=<something>,但不确定是否可以将其设置为仅为标准输入,您需要先收集输入,然后将其传递给子进程。如果您有另一个生成输出的进程,并且希望在此处将其用作stdin,则可以肯定地执行此操作-即proc2的标准输入是proc1的输出。因此,proc1将是您的dd命令,而proc2将是您想要将输出传递给的任何进程。不确定这是否有所帮助-我对确切要求有点不清楚。 - michjnich
@urbanespaceman 我的需求只是将我在 bytearray 中拥有的数据传递给 dd 命令,以便写入磁盘。已编辑问题。 - The amateur programmer
2个回答

2

针对提问者要求的通过 stdin 传递给 subprocess.run() 的具体操作,请按以下方式使用 input

#!/usr/bin/python3
import subprocess

data = bytes("Hello, world!", "ascii")

p = subprocess.run(
    "cat -", # The - means 'cat from stdin'
    input=data,
    # stdin=... <-- don't use this
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)

print(p.stdout.decode("ascii"))
print(p.returncode)

# Hello, world!
# 0

2
您可以直接调用Popen,将一个命令的输出传递给另一个命令。
file_cmd1 = <your dd command>
file_cmd2 = <command you want to pass dd output to>

proc1 = Popen(sh_split(file_cmd1), stdout=subprocess.PIPE)
proc2 = Popen(file_cmd2, [shell=True], stdin=proc1.stdout, stdout=subprocess.PIPE)
proc1.stdout.close()

据我所知,这个命令在字节输出上可以正常工作。
如果您只想将数据传递给进程的stdin,则在您的情况下,最好执行以下操作:
out = bytearray(b"Some data here")
p = subprocess.Popen(sh_split("dd of=/../../somefile.data bs=32"), stdin=subprocess.PIPE)
out = p.communicate(input=b''.join(out))[0]
print(out.decode())#Prints the output from the dd

我不知道如何运行一个命令来获取stdout并将其传递给第二个Popen。我能否直接在proc1.stdout的位置上使用存储数据的bytearray类型变量呢?这些数据是在Python程序中生成并存储在bytearray类型变量中的。 - The amateur programmer
对不起,我想我误解了。stdin 需要一个字节序列,所以如果你直接将 bytearray 传递给它,我想这应该可以工作... 如果不行,那就直接发送原始的字节序列,而不将其转换为 bytearray - michjnich
我应该如何输入字节序列?尝试了以下代码:proc = subprocess.Popen(shsplit("dd of=/home/xyz/test.txt bs=1 seek=0"), stdin=b'Hello World', stdout=subprocess.PIPE) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.8/subprocess.py", line 804, in __init__ errread, errwrite) = self._get_handles(stdin, stdout, stderr) File "/usr/lib/python3.8/subprocess.py", line 1475, in _get_handles p2cread = stdin.fileno() AttributeError: 'bytes' object has no attribute 'fileno' - The amateur programmer
算了,我已经找到解决方案了。我需要使用 proc.communicate() 将数据传递给 stdin。 - The amateur programmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接