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: 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
Vous devez vous connecter pour publier un commentaire.
.readlines()
lit tous lignes. Pas étonnant que vous ne voyez pas tout de sortie jusqu'à ce que le sous-processus se termine. Vous pouvez utiliser.readline()
au lieu de lire ligne par ligne dès que le processus secondaire vide ses stdout tampon:Si vous avez déjà
pexpect
ensuite, vous pouvez l'utiliser pour contourner le bloc-tampon question:Voir aussi
stdbuf
,pty
de solutions à base d' de la question que j'ai lié dans les commentaires.J'ai ajouté explicitement
pexpect
solution. Pourriez-vous mettre à jour votre question afin de fournir un ensemble minimal exemple qui montre ce qui "ne marche pas" signifie dans votre cas particulier, avec lasubprocess
code de ma réponse? (par exemple,"my noisy stuff"
est'{ echo a; sleep 2; echo b;}', shell=True
et il est essentiel d'obtenir des'a'
sans attendre2
secondes)Édité, j'ai collé terme de la production. De toute façon votre pexpect solution fonctionne comme un charme. Impression de la sortie en temps réel. Je vous remercie beaucoup.!!!
avez-vous essayé avec
bufsize=1
?mais tout de même sortie. Je suppose que ce serait une bonne idée de nettoyer le tampon à chaque itération de la boucle.
OriginalL'auteur jfs