L'analyse pexpect de sortie

Je suis en train d'analyser en temps réel la sortie d'un programme bloc-mise en mémoire tampon, ce qui signifie que la sortie n'est pas disponible jusqu'à ce que le processus se termine. Ce dont j'ai besoin est juste d'analyser ligne par ligne, de filtre et de gérer les données à partir de la sortie, comme il peut courir pendant des heures.

J'ai essayé de capturer la sortie avec des sous-processus.Popen(), mais oui, comme vous pouvez le deviner, Popen ne pouvez pas gérer ce genre de comportement, il conserve la mise en mémoire tampon jusqu'à la fin du processus.

from subprocess import Popen, PIPE

p = Popen("my noisy stuff ", shell=True, stdout=PIPE, stderr=PIPE)
for line in p.stdout.readlines():
    #parsing text and getting data

J'ai donc trouvé pexpect, qui imprime la sortie en temps réel, comme il traite le stdout dans un fichier, je pourrais même faire un sale coup l'impression d'un fichier et l'analyser en dehors de la fonction. Mais ok, c'est trop sale, même pour moi 😉

import pexpect
import sys

pexpect.run("my noisy stuff", logfile=sys.stdout)

Mais j'imagine que ça doit mieux pythonic façon pour ce faire, il suffit de gérer la sortie standard (stdout) comme sous-processus. Popen. Comment puis-je faire cela?

EDIT:

L'exécution de J. F. proposition:

C'est délibérément mal de vérification, il faut environ 25 secondes. pour arrêter.

from subprocess import Popen, PIPE

command = "bully mon0 -e ESSID -c 8 -b aa:bb:cc:dd:ee:00 -v 2"

p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)

for line in iter(p.stdout.readline, b''):
    print "inside loop"
    print line

print "outside loop"
p.stdout.close()
p.wait()


#$ sudo python SCRIPT.py
                                ### <= 25 secs later......
# inside loop
#[!] Bully v1.0-21 - WPS vulnerability assessment utility

#inside loop
#[!] Using 'ee:cc:bb:aa:bb:ee' for the source MAC address

#inside loop
#[X] Unable to get a beacon from the AP, possible causes are

#inside loop
#[.]    an invalid --bssid or -essid was provided,

#inside loop
#[.]    the access point isn't on channel '8',

#inside loop
#[.]    you aren't close enough to the access point.

#outside loop

À l'aide de cette méthode à la place:
EDIT: en Raison de grands retards et les délais d'attente à la sortie, j'ai eu à corriger l'enfant, et a ajouté quelques hacks, alors au final le code ressemble à ceci

import pexpect

child = pexpect.spawn(command)
child.maxsize = 1  #Turns off buffering
child.timeout = 50 # default is 30, insufficient for me. Crashes were due to this param.
for line in child:
    print line,

child.close()

Donne le même résultat, mais il imprime des lignes en temps réel. Alors... RÉSOLU Merci @J. F. Sebastian

connexes: Python sous-processus readlines() se bloque
connexes: Python: lire le streaming d'entrée de sous-processus.communiquer()
Avez-vous besoin d'envoyer des réponses à la commande ou que vous venez de lire la sortie? Avez-vous besoin d'une ligne de tampon de sortie ou d'un bloc tampon de sortie (p. ex., à l'aide d'une 4096 octets de la mémoire tampon) est suffisant pour un programme qui peut exécuter des heures?
Salut J. F. j'ai juste besoin d'analyser les données en sortie. Le programme lui-même les audits des flux de données, donc je veux gérer d'AUTRES programmes basés dans le comportement de la sortie de ce programme. Donc mon code en permanence la lecture de sortie.
utilisation print line, (note: la virgule à la fin -- sys.stdout.softspace hack) pour éviter de doubler les retours à la ligne.

OriginalL'auteur peluzza | 2013-11-25