2014-07-24 3 views
0

Я понимаю, что связь() будет ждать завершения процесса, хранения данных в буфере памяти и возврата. Я думал, что приведенный ниже код не будет эффективным, поскольку я хочу запросить все интересные rpms и собрать информацию по каждому из них. Это будет включать ~ 15 rpms на одном сервере для до 200 серверов в одной группе.subprocess.Popen.communicate not effient с большими наборами данных?

Я хочу запросить базу данных RPM в Linux и получить информацию из всех. Rpm и сохранить ее.

В Linux я хотел бы сделать это:

rpm -qa --qf '%{NAME} %{VERSION} %{RELEASE}\n' | grep this 

и я могу использовать все --queryformat RPM обеспечивает.

Итак, у меня это в 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 

Как я могу сделать это эффективным? Я видел, что я могу использовать потоки и потоки, но я не знаю, как это сделать.

+0

RPM имеет программный интерфейс API с привязками Python, описанных здесь: http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-rpm-programming-python.html. Может быть, родная интеграция лучше, чем скручивание оболочки скрипта и скрипинг экрана? –

+0

Я сделал хороший сценарий, который использовал это, к сожалению, я использую 2.7.8, и он не включен! – case

ответ

0

Примечание. Чтение данных буферизируется в памяти, поэтому не используйте этот метод, если размер данных является большим или неограниченным.

«Большой» в этом случае является неопределенным, но он имеет тенденцию означать несколько мегабайт, если не намного больше. Выходной сигнал rpm -qi для одного RPM должен быть нигде рядом с этим размером. Здесь я бы не стал беспокоиться об эффективности.

Кроме того, нет необходимости строить командную строку как одну строку, чтобы разделить ее снова. Составьте список, чтобы начать:

p = subprocess.Popen(['rpm', '-qi', rpm, stdout=subprocess.PIPE) 

Чтобы избежать строительства большого списка в памяти всех РПМ (что матч 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 
+0

Хорошо. Я не думаю, что команда rpm будет работать в команде. Это строка. Я должен пройти через .format. – case

+0

Предполагая, что 'rpm' - это просто имя пакета, нет необходимости использовать' format'. – chepner

+0

Извините за путаницу. rpm - это имя каждого пакета в 'для rpm в getrpms():' getrpm() получает все rpms! BTW выходной файл будет 5 МБ текста. – case

Смежные вопросы