我正在使用subprocess模块与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)

我知道进程挂起的原因是缓冲区重定向到子进程。管道被填满,这会阻止进程进一步编写。
我想知道是否有任何方法可以避免缓冲区已满的情况,以便我的程序继续执行而不出现任何挂起问题?

最佳答案

实际问题是模式和文件名之间缺少空白,因此grep等待标准输入(stdin)的输入。
“buffer full”(.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')

09-27 12:02