在Python中替换subprocess.PIPE?

在Python中替换subprocess.PIPE?,python,python-2.7,python-3.x,Python,Python 2.7,Python 3.x,我正在使用子流程模块与linux命令的输出交互。下面是我的代码 import subprocess import sys file_name = 'myfile.txt' p = subprocess.Popen("grep \"SYSTEM CONTROLLER\" "+ file_name, stdout=subprocess.PIPE, shell=True) (output, err) = p.communicate() print output.strip() p = subpro

我正在使用子流程模块与linux命令的输出交互。下面是我的代码

import subprocess
import sys

file_name = 'myfile.txt'
p = subprocess.Popen("grep \"SYSTEM CONTROLLER\" "+ file_name, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
print output.strip()

p = subprocess.Popen("grep \"controller\|worker\" "+ file_name, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
lines = output.rstrip().split("\n")
print lines
我的程序在执行第二个子进程时挂起,即

p = subprocess.Popen("grep \"controller\|worker\""+ file_name,stdout=subprocess.PIPE, shell=True)
我知道进程挂起的原因是缓冲区被重定向到了subprocess.PIPE被填充,这会阻止进程进一步写入

我想知道是否有任何方法可以避免缓冲区已满的情况,从而使我的程序继续执行,而不会出现任何挂起问题?

正如它在:

注意:读取的数据缓冲在内存中,因此不要使用此方法 如果数据大小较大或不受限制

相反,请在生成文本时使用以下命令阅读文本:

output = p.stdout.read()

只要您在阅读时没有其他管道(如stderr)填满,就不应该阻止该过程。

实际问题是模式和文件名之间缺少空格,因此
grep
等待标准输入(stdin)的输入

“缓冲区已满”(
.communicate()
不易受影响)或
p.stdout.read()
(它不修复任何问题:它将输出加载到内存中,与
不同。communicate()
如果使用多个管道,它将失败)在这里是一个危险因素

删除
shell=True
并为命令使用列表参数:

#!/usr/bin/env python
from subprocess import Popen, PIPE

p = Popen(["grep", r"controller\|worker", file_name], stdout=PIPE)
output = p.communicate()[0]
if p.returncode == 0:
    print('found')
elif p.returncode == 1:
    print('not found')
else: 
    print('error')

我认为(但不确定)错误在于在两个子流程中使用双引号。使用double分隔命令字符串,使用single分隔或反之亦然。还可以考虑使用<代码> OS。Stor()/代码> @ FATTIGIDLE错误不使用双引号。这是因为在许多其他文档中都提到使用管道。为什么要在子流程中执行
grep
?为什么不直接使用Python的
re
模块来执行regex操作呢?我的要求是使用
grep
从文件中写入的内容中查找字符串,然后使用
re
模块在字符串中执行更多的验证@PM2Ring@fattidare:
os.system
与子进程模块相比非常有限,不推荐使用它。特别是,
os.system
只返回它运行的命令的退出代码,不允许您访问该命令的IO。From:“子流程模块允许您生成新的流程,连接到它们的输入/输出/错误管道,并获取它们的返回代码。此模块旨在替换几个较旧的模块和函数:[……]os.system”。