L'obtention de la sortie en temps réel à l'aide de sous-processus

Je suis en train d'écrire un script pour un programme en ligne de commande (svnadmin vérifier) qui affiche une belle progression de l'indicateur pour l'opération. Cela m'oblige à être en mesure de voir chaque ligne de la sortie de l'enveloppé programme dès qu'elle est sortie.

J'ai pensé que je venais d'exécuter le programme à l'aide subprocess.Popen, utilisez stdout=PIPE, puis de lire chaque ligne comme il est venu dans et à agir en conséquence. Cependant, quand j'ai couru le code suivant, la sortie semble être tamponnée quelque part, le faisant apparaître dans deux segments, les lignes 1 à 332, puis 333 grâce à 439 (la dernière ligne de sortie)

from subprocess import Popen, PIPE, STDOUT

p = Popen('svnadmin verify /var/svn/repos/config', stdout = PIPE, 
        stderr = STDOUT, shell = True)
for line in p.stdout:
    print line.replace('\n', '')

Après avoir examiné la documentation sur les sous-processus un peu, j'ai découvert le bufsize paramètre Popen, j'ai donc essayé de réglage bufsize à 1 (tampon de chaque ligne) et 0 (pas de tampon), mais ni la valeur semblé changer la façon dont les lignes ont été livrés.

À ce stade, je commençais à saisir pour la paille, j'ai donc écrit à la suite de la sortie de la boucle:

while True:
    try:
        print p.stdout.next().replace('\n', '')
    except StopIteration:
        break

mais il a obtenu le même résultat.

Est-il possible d'obtenir en temps réel le programme de sortie d'un programme exécuté à l'aide d'un processus secondaire? Est-il une autre option en Python qui est compatible (pas exec*)?

  • Avez-vous essayé l'omission de la sydout=PIPE de sorte que le sous-processus écrit directement à votre console, en contournant le processus parent?
  • Le truc, c'est que j'ai envie de lire la sortie. Si c'est directement la sortie de la console, comment pourrais-je le faire? Aussi, je ne veux pas que l'utilisateur de voir la sortie de la enveloppé programme, juste à ma sortie.
  • Alors pourquoi un "temps réel" afficher? Je ne reçois pas le cas d'utilisation.
  • Ne pas utiliser le shell=True. Il needlessy appelle votre shell. Utiliser p = Popen(['svnadmin', 'vérifier', '/var/svn/repos/config'], stdout=PIPE, stderr=STDOUT) au lieu
  • Fondamentalement, svnadmin vérifier imprime une ligne de sortie pour chaque révision, qui est vérifiée. Je voulais faire un bon indicateur de progrès qui ne cause pas de quantités excessives de sortie. Un peu comme wget, par exemple
  • J'ai essayé en omettant shell=True lorsque je travaillais avec cela, mais il ne serait jamais exécuter sans elle. J'ai même utilisé le chemin d'accès complet à svnadmin dans le cas où le CHEMIN n'est pas défini si j'ai utilisé shell=Faux, mais ça n'a pas réglé non plus.
  • Vous avez besoin de fractionner la commande en vous-même pour être en mesure d'omettre le shell=True mais c'est une simple modification. @nosklo commentaire vous montre comment; passer le premier argument est une liste de jetons, pas une seule chaîne.

InformationsquelleAutor Chris Lieb | 2009-04-29