Exec gebruiken in een for-lus in python

Ik probeer een for-lus uit te voeren die door elke regel van de uitvoer van een commando loopt. Bijvoorbeeld:

for line in exec 'lspci | grep VGA':
    count = count + 1

Om te proberen het aantal videokaarten in een systeem te installeren. Maar het lijkt niet de syntax op de for-luslijn te zetten.

Moet ik een bibliotheek importeren voor exec? Of gebruik ik het verkeerd? Of allebei?

Bedankt

3

4 antwoord

exec executes Python code, not an external command. You're looking for subprocess.Popen():

import subprocess
p = subprocess.Popen('lspci', stdout=subprocess.PIPE)
for line in p.stdout:
  if 'VGA' in line:
    print line.strip()
p.wait()

Op mijn doos drukt dit uit

01:00.0 VGA compatible controller: nVidia Corporation GF104 [GeForce GTX 460] (rev a1)
6
toegevoegd
Ik probeerde dit, zegt dat stdout global niet is gedefinieerd. Moet ik iets anders importeren?
toegevoegd de auteur Danny, de bron
Sorry, ik moet iets verpest hebben, maar werkt nu. Bedankt!
toegevoegd de auteur Danny, de bron

Het zoekwoord exec voert Python-code . Het start geen nieuwe processen.

Probeer in plaats hiervan de subproces -module.

lines = subprocess.check_output(["lspci"]).split('\n')
count = sum('VGA' in line for line in lines)
5
toegevoegd
Dit zou gewerkt hebben, maar RHEL5.5 lijkt te worden geleverd met 2.4.3 en ik kan niet alle systemen upgraden die ik nodig heb om dit in te zetten. Hoe dan ook
toegevoegd de auteur Danny, de bron

U wilt popen (of iets dergelijks) gebruiken. exec excelleert python-code. Bijvoorbeeld:

exec('x = 4')
print x  # prints 4

Ook mis je haakjes, waardoor het niet grammaticaal is. exec is een functie:

for line in exec('lspci | grep VGA'):  # this still does not do what you want
    count = count + 1

U kunt wc -l gebruiken om het aantal regels in één keer te meten.

import os
count = os.popen('lspci | grep VGA | wc -l').read()
0
toegevoegd
subproces module vervangen door os.popen
toegevoegd de auteur Corey Goldberg, de bron

Ik heb deze functie in python voor dat soort doeleinden geschreven

(De reden om tempfile te gebruiken is dat als je een subproces opent en de stdout vastlegt met behulp van subproces.PIPE, als de stdout meer dan 64k aan data krijgt, python voor altijd blijft hangen.)

import logging
import tempfile
import subprocess
import os


def getPipedCommandOut(cmd):
    """
    cmd - command to execute

    gathers output of command (stderr and stdout) into a temp file

    returns the output of the command
    """
    logging.debug('starting %s' % cmd)

    temp = tempfile.TemporaryFile('w+t')
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.STDOUT,stdout=temp.fileno(), shell=True)
        #pid, status = os.waitpid(p.pid,0) #@UnusedVariable
        status = p.wait()
        temp.seek(0)
        out = temp.read()
        if status != 0:
            raise CommandRunError("COMMAND: %s\tFAILED: %s%s%s" % (cmd, status, os.linesep, out))
        logging.debug('finished %s' % cmd)
    finally: 
        temp.close()
    return out

dan om te gebruiken met uw code:

lspciOutput = getPipedCommandOut('lspci | grep VGA')
for line in lspciOutput:
    count = count + 1
0
toegevoegd
Je programma (je kunt Python hiervoor niet de schuld geven) zou hangen omdat je p.wait() aanroept voordat elke uitvoer van de pijp leest. De grootte van je OS-pipe-buffer is blijkbaar 64.000, dus het programma zal nooit worden voltooid voordat alle uitvoer is geschreven. In plaats daarvan kunt u de pipe-uitvoer lezen vóór door p.wait() aan te roepen, zodat u helemaal geen tijdelijk bestand gebruikt. Of u kunt zoiets als subproces.communicate die dit allemaal voor u afhandelt.
toegevoegd de auteur Greg Hewgill, de bron
Uw aanpak zou nodig zijn als u een zeer grote hoeveelheid uitvoer verwacht (meer dan wat redelijkerwijs in het RAM-geheugen past, zoals honderden megabytes) en u deze naar schijf wilt spoolen. Voor de meeste doeleinden is het verzamelen van de uitvoer in RAM prima.
toegevoegd de auteur Greg Hewgill, de bron
Overeengekomen dat dit een pip-buffer grootte probleem is - geen python-bug. Maar ik hou er voorlopig van de tijdelijke oplossing tijdelijke. Denkt u dat het enige nadelen heeft in vergelijking met het lezen en bijvoegen van de tekenreeks uit de pijp of het gebruik van communicatie?
toegevoegd de auteur uncreative, de bron