2017-08-18 1 views
2

J'ai besoin de diffuser à une liste la sortie d'un fichier, je reçois les données correctes, mais avec beaucoup d'ordure à la fin et ne pas comprends ce que je fais de mal.Python: Junk reçu quand readline() un processus appelé avec Popen()

Le (ce que je pensais était assez simple) Code popen est:

stream = [] 
p = Popen(["python", "-u", "test.py"], stdout=PIPE, bufsize=1) 

while p.poll() is None: 
    stream.append(p.stdout.readline()) 

print stream 
print 'Returned: {0}'.format(p.returncode) 

La sortie d'appeler ceci est:

La sortie de l'exécuter est la suivante:

['[INDEX 0] Current index position\n', '[INDEX 1] Current index position\n', '[INDEX 2] Current index position\n', '[INDEX 3] Current index position\n', '[INDEX 4] Current index position\n', 'exiting. 
...\n', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 
'', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 
'', '', '', '', '', '', '', '', '', '', '', '', '', ''] 
Returned: -4 

test .py est:

index = 0 

while True: 
    print '[INDEX {0}] Current index position'.format(index) 
    index += 1 
    if index == 5: break 

import sys 
print 'exiting....' 
sys.exit(-4) 
+0

Sur quel système êtes-vous. Cela fonctionne sur Linux. Essayez de définir 'bufsize = -1' (système par défaut) –

+0

Le système d'exploitation est Windows 10. Je reçois les données réelles, mais avec des déchets supplémentaires. Suis-je manquer un contrôle que le processus a terminé. L'utilisation de bufsize = -1 n'a fait aucune différence –

Répondre

3

Le problème ici est que votre si condition est incorrect:

while p.poll() is None: 
    stream.append(p.stdout.readline()) 

Cela signifie « alors que le processus est en cours d'exécution, lisez une ligne ». Mais ce n'est pas ce que tu veux. Ce que vous voulez vraiment, c'est "alors qu'il y a plus de sortie, lisez une ligne". Le code que vous avez écrit lit des lignes vides pendant la fermeture du processus, c'est donc d'où proviennent toutes les chaînes vides.

Ce que vous devez faire est plutôt ceci:

for line in p.stdout: 
    stream.append(line) 

Cela arrête correctement les lignes de lecture quand il n'y a pas plus de puissance, et il est garanti à lire tous de la sortie. (Théoriquement, votre code peut quitter la boucle avant d'avoir traité toute la sortie si le processus produit une sortie plus rapide que vous la traitez.Vous pouvez l'émuler en ajoutant un time.sleep(0.1) à votre boucle.)

+0

Merci, c'est très utile - devrais-je coder pour protéger contre le traitement plus rapide que je ne peux le traiter? –

+0

@PaulMorriss Eh bien, oui - 'pour la ligne dans p.stdout:' résout ce problème et les chaînes vides dans votre sortie de toute façon. –