如果可能的话,我正在寻找更好的方法来做到这一点:
import subprocess
f = open('temp.file', 'w+')
f.write('hello world')
f.close()
out = subprocess.check_output(['cat', 'temp.file'])
print out
subprocess.check_output(['rm', 'temp.file'])
在这个例子中,我创建了一个文件并将其作为输入传递给cat
(实际上,我运行的不是cat
而是解析输入pcap
文件的其他程序)。
我想知道的是,在 Python 中是否有一种方法可以创建一个包含一些内容的"类似文件的对象",并将这个类似文件的对象作为命令行程序的输入。如果可能的话,我认为这比将文件写入磁盘然后删除该文件更有效。
check_output
采用stdin
输入参数来指定一个类似文件的对象来连接到进程的标准输入。
with open('temp.file') as input:
out = subprocess.check_output(['cat'], stdin=input)
此外,没有必要掏出时间来运行rm
;你可以直接从Python中删除文件:
os.remove('temp.file')
您可以写入临时文件
import subprocess
from tempfile import TemporaryFile
f = TemporaryFile("w")
f.write("foo")
f.seek(0)
out = subprocess.check_output(['cat'],stdin=f)
print(out)
b'foo'
如果您只想写入类似对象的文件并获取内容:
from io import StringIO
f = StringIO()
f.write("foo")
print(f.getvalue())
如果程序配置为从stdin
读取,则可以使用 Popen.communication:
>>> from subprocess import Popen, PIPE
>>> p = Popen('cat', stdout=PIPE, stdin=PIPE, stderr=PIPE)
>>> out, err = p.communicate(input=b"Hello world!")
>>> out
'Hello world!'
如果命令只接受文件名,如果它不从其 stdin 读取输入,即,如果你不能使用 stdin=PIPE
+ .communicate()
或 stdin=real_file
那么你可以尝试/dev/fd/#
文件名:
#!/usr/bin/env python3
import os
import subprocess
import threading
def pump_input(pipe):
with pipe:
for i in range(3):
print(i, file=pipe)
r, w = os.pipe()
try:
threading.Thread(target=pump_input, args=[open(w, 'w')]).start()
out = subprocess.check_output(['cat', '/dev/fd/'+str(r)], pass_fds=[r])
finally:
os.close(r)
print('got:', out)
没有内容接触磁盘。输入通过管道直接传递到子进程。
如果你有一个类似文件的对象,但不是真正的文件(否则,只需将其名称作为命令行参数传递),那么pump_input()
可能如下所示:
import shutil
def pump_input(pipe):
with pipe:
shutil.copyfileobj(file_like_object, pipe)