Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用StringIO作为标准输入与Popen_Python_Subprocess - Fatal编程技术网

Python 使用StringIO作为标准输入与Popen

Python 使用StringIO作为标准输入与Popen,python,subprocess,Python,Subprocess,我想用Python编写以下shell脚本(当然grep.实际上是一个更复杂的命令): 我尝试了这个(它缺少一个与cat日志文件相当的文件): 但是我得到了错误AttributeError:StringIO实例没有属性“fileno” 我知道我应该使用subprocess.communicate()而不是StringIO来向grep进程发送字符串,但我不知道如何将字符串和文件混合使用。除了之外,不要使用裸,它可能会捕获太多。在Python 3中: p = subprocess.Popen(['gr

我想用Python编写以下shell脚本(当然
grep.
实际上是一个更复杂的命令):

我尝试了这个(它缺少一个与
cat日志文件
相当的文件):

但是我得到了错误
AttributeError:StringIO实例没有属性“fileno”


我知道我应该使用
subprocess.communicate()
而不是StringIO来向
grep
进程发送字符串,但我不知道如何将字符串和文件混合使用。

除了之外,不要使用裸
,它可能会捕获太多。在Python 3中:

p = subprocess.Popen(['grep', '...'], stdin=subprocess.PIPE, 
                                      stdout=subprocess.PIPE)
output, output_err = p.communicate(myfile.read())
#!/usr/bin/env python3
from subprocess import check_output

try:
    file = open('somefile', 'rb', 0)
except FileNotFoundError:
    output = check_output(cmd, input=b'somefile not found')
else:
    with file:
        output = check_output(cmd, stdin=file)
它适用于大型文件(文件在文件描述符级别重定向,无需将其加载到内存中)

如果您有一个类似文件的对象(没有真正的
.fileno()
);您可以使用
.write()
方法直接写入管道:

#!/usr/bin/env python3
import io
from shutil import copyfileobj
from subprocess import Popen, PIPE
from threading import Thread

try:
    file = open('somefile', 'rb', 0)
except FileNotFoundError:
    file = io.BytesIO(b'somefile not found')

def write_input(source, sink):
    with source, sink:
        copyfileobj(source, sink)

cmd = ['grep', 'o']
with Popen(cmd, stdin=PIPE, stdout=PIPE) as process:
    Thread(target=write_input, args=(file, process.stdin), daemon=True).start()
    output = process.stdout.read()

不能使用
StringIO
对象提供流程输入;改为使用
subprocess.PIPE
。@MartijnPieters如我所说(最后一句),“我知道我应该使用subprocess.communicate()而不是StringIO将字符串发送到grep进程,但我不知道如何混合字符串和文件。”为什么不从打开的文件对象读取,写入管道?如果没有打开的文件,写下替代文本。为什么不使用grep呢?哦,好的。您可以使用一些库以完全python的方式来完成它。但是我明白你的意思。这不是把
myfile
的全部内容读入内存,为它分配一个字符串,等等吗。?是否应该有一种方法将文件句柄直接传递给下一个进程?使用
copyfileobj()
的简洁建议。你能编辑你的答案来澄清为什么需要一个线程吗?我想在读取
进程
es输出时需要避免死锁。@smbear如果不使用线程(或async.io),您认为会发生什么?
#!/usr/bin/env python3
from subprocess import check_output

try:
    file = open('somefile', 'rb', 0)
except FileNotFoundError:
    output = check_output(cmd, input=b'somefile not found')
else:
    with file:
        output = check_output(cmd, stdin=file)
#!/usr/bin/env python3
import io
from shutil import copyfileobj
from subprocess import Popen, PIPE
from threading import Thread

try:
    file = open('somefile', 'rb', 0)
except FileNotFoundError:
    file = io.BytesIO(b'somefile not found')

def write_input(source, sink):
    with source, sink:
        copyfileobj(source, sink)

cmd = ['grep', 'o']
with Popen(cmd, stdin=PIPE, stdout=PIPE) as process:
    Thread(target=write_input, args=(file, process.stdin), daemon=True).start()
    output = process.stdout.read()