Python subprocess.Popen.communication与大数据集不有效?
我知道communicate()将等待进程完成,将数据存储在内存缓冲区中并返回。我认为下面的代码不会很有效,因为我想查询所有感兴趣的RPM并收集每个RPM的信息。这将涉及一台服务器上约15 RPM,一个组中最多200台服务器 我想在Linux中查询RPM数据库,从每个.RPM中获取信息并存储它 在Linux中,我会这样做:Python subprocess.Popen.communication与大数据集不有效?,python,linux,shell,bash,Python,Linux,Shell,Bash,我知道communicate()将等待进程完成,将数据存储在内存缓冲区中并返回。我认为下面的代码不会很有效,因为我想查询所有感兴趣的RPM并收集每个RPM的信息。这将涉及一台服务器上约15 RPM,一个组中最多200台服务器 我想在Linux中查询RPM数据库,从每个.RPM中获取信息并存储它 在Linux中,我会这样做: rpm -qa --qf '%{NAME} %{VERSION} %{RELEASE}\n' | grep this 我可以使用RPM提供的所有--queryformat
rpm -qa --qf '%{NAME} %{VERSION} %{RELEASE}\n' | grep this
我可以使用RPM提供的所有--queryformat
我用Python编写了这个程序,它很有效。但我想让它变得简单
def getrpms():
queryall = []
rpmqa = subprocess.Popen(['rpm', '-qa'], stdout=subprocess.PIPE,)
grep = subprocess.Popen(['grep', 'stuff'], stdin=rpmqa.stdout, stdout=subprocess.PIPE,)
sort = subprocess.Popen(['sort', '-r'], stdin=grep.stdout, stdout=subprocess.PIPE,)
end_of_pipe = sort.stdout
for line in end_of_pipe:
queryall.append(line.strip())
return queryall
def rpminfo():
for rpm in getrpms():
command = "rpm -qi {} ".format(rpm)
args = shlex.split(command)
p = subprocess.Popen(args, stdout=subprocess.PIPE)
pl = p.communicate() # returns a tuple
print pl
我怎样才能使它更有效率?我看到我可以使用线程和流,但我不知道如何使用
注意,读取的数据缓冲在内存中,因此,如果数据大小较大或不受限制,请不要使用此方法
在这种情况下,“大”是模糊的,但它往往意味着多兆字节,如果不是更多的话。单个rpm的rpm-qi
的输出不应接近该大小。我不会担心这里的效率
除此之外,不需要将命令行构建为一个字符串来再次拆分它。创建要启动的列表:
p = subprocess.Popen(['rpm', '-qi', rpm, stdout=subprocess.PIPE)
为了避免在内存中建立一个包含所有RPM(匹配
stuff
)的大型列表,请将getrpms()
改为生成器。这样,您就不必一次读取子流程中的所有文本行;您可以一次读取和处理一行
def getrpms():
rpmqa = subprocess.Popen(['rpm', '-qa'], stdout=subprocess.PIPE)
grep = subprocess.Popen(['grep', 'stuff'], stdin=rpmqa.stdout, stdout=subprocess.PIPE)
sort = subprocess.Popen(['sort', '-r'], stdin=grep.stdout, stdout=subprocess.PIPE,)
for line in sort.stdout:
yield line
RPM有一个带有Python绑定的编程API,如下所述:。也许本机集成比shell脚本管道和屏幕抓取更好?我做了一个很好的脚本,使用了它,不幸的是,我使用的是2.7.8,它没有包括在内!好啊我认为rpm不能在命令中工作。这是一根绳子。我必须通过.format传递它。假设
rpm
只是一个包的名称,那么就没有必要使用format
。很抱歉造成混淆。rpm是getrpm()中rpm的中每个包的名称:
getrpm()获取所有rpm!顺便说一句,输出文件将是5MB的文本。