我正在使用子进程模块与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正在填充,这会阻止进程进一步写入。
我想知道是否有办法避免缓冲区已满,以便我的程序继续执行而不会出现任何挂起问题?
答案 0 :(得分:3)
正如https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate所述:
注意:读取的数据缓冲在内存中,因此请勿使用此方法 如果数据大小很大或无限制。
相反,请使用file objects读取生成的文本:
output = p.stdout.read()
只要在您阅读时没有其他管道(例如stderr)填满,该过程就不会被阻止。
答案 1 :(得分:3)
实际问题是模式和文件名之间缺少空格,因此grep
等待标准输入(stdin)的输入。
"缓冲区已满" (.communicate()
不易受影响)或p.stdout.read()
(它不会修复任何内容:它会将输出加载到内存中,而不像{{ 1}}如果使用多个管道则失败)这里是红鲱鱼。
删除.communicate()
并使用命令的list参数:
shell=True