我可以将io.BytesIO()流传递给Python中的subprocess.popen()吗?

Red*_*dro 8 python subprocess pipe popen bytesio

我想io.BytesIO() bytetream到一个单独的程序使用subprocess.popen() ,但我不知道如何,或者如果这是在所有可能的.文档和示例都是关于文本和换行的.

当我掀起这样的事情时:

import io
from subprocess import *

stream = io.BytesIO()
someStreamCreatingProcess(stream)

command = ['somecommand', 'some', 'arguments']  
process = Popen(command, stdin=PIPE)
process.communicate(input=stream)
Run Code Online (Sandbox Code Playgroud)

我明白了

Traceback (most recent call last):
  File "./test.py", line 9, in <module>
    procOut         = process.communicate(input=stream)
  File "/usr/lib/python2.7/subprocess.py", line 754, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.7/subprocess.py", line 1322, in _communicate
    stdout, stderr = self._communicate_with_poll(input)
  File "/usr/lib/python2.7/subprocess.py", line 1384, in _communicate_with_poll
    chunk = input[input_offset : input_offset + _PIPE_BUF]
TypeError: '_io.BytesIO' object has no attribute '__getitem__'
Run Code Online (Sandbox Code Playgroud)

我认为popen()仅适用于文本.我错了吗?
有没有不同的方法来做到这一点?

jfs*_*jfs 6

正如@falsetru所说,你不能BytesIO()直接流对象; 你需要先从它获得一个字节串.这意味着stream 您致电stream.getvalue()传递之前,所有内容都应该已经写入process.communicate().

如果您想要而不是一次提供所有输入,那么您可以删除BytesIO()对象并直接写入管道:

from subprocess import Popen, PIPE

process = Popen(['command', 'arg1'], stdin=PIPE, bufsize=-1)
someStreamCreatingProcess(stream=process.stdin) # many `stream.write()` inside
process.stdin.close() # done (no more input)
process.wait()
Run Code Online (Sandbox Code Playgroud)

someStreamCreatingProcess()在完成写入流之前不应该返回.如果它立即返回,那么它应该stream.close()在将来的某个时候调用(process.stdin.close()在代码中删除):

from subprocess import Popen, PIPE

process = Popen(['command', 'arg1'], stdin=PIPE, bufsize=-1)
someStreamCreatingProcess(stream=process.stdin) # many `stream.write()` inside
process.wait() # stream.close() is called in `someStreamCreatingProcess`
Run Code Online (Sandbox Code Playgroud)


fal*_*tru 5

根据subprocess.Popen.communicate:

可选的输入参数应该是要发送到子进程的字符串,如果没有数据应该发送给子进程,则应为None.


要从BytesIOobject 获取(字节)字符串值,请使用getvalue:

process.communicate(input=stream.getvalue())
Run Code Online (Sandbox Code Playgroud)

  • @Redsandro,当你调用`subprocess.Popen`时,`stream`是否包含所有数据? (2认同)