L'obtention de la sortie d'un processus au moment de l'exécution
Je suis aide d'un script python pour exécuter un processus à l'aide de subprocess.Popen
et, simultanément, de stocker le résultat dans un fichier texte ainsi que de l'imprimer sur la console. C'est mon code:
result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in result.stdout.readlines(): #read and store result in log file
openfile.write("%s\n" %line)
print("%s" %line)
Code ci-dessus fonctionne très bien, mais ce qu'il fait c'est qu'il remplit d'abord le processus et stocke le résultat dans résultat variable. Après que pour la boucle magasins de la sortie ainsi que de l'imprimer.
Mais je veux que la sortie au moment de l'exécution (comme mon processus peut prendre des heures pour compléter, je n'obtenez pas de résultat pour toutes ces heures).
Donc, il y a une autre fonction qui me donne de la sortie de manière dynamique (à l'exécution), signifie que dès que le processus donne la première ligne, il doit être imprimé.
file
objet de la stdout
(ou stdin
, ou stderr
argument). Ensuite, vous avez à interroger ce fichier. Subprocess
a été inventé pour vous épargner cette douleur, mais il semble que vous n'avez pas le choix. Bonne chance."il remplit d'abord le processus et stocke le résultat dans la suite" - qui est tout simplement pas vrai.
"il remplit d'abord le processus et stocke le résultat dans result" - qui n'est tout simplement pas vrai. Eh bien, quand je suis en cours d'exécution Popen de commande, il continue à fonctionner jusqu'à ce que le processus est terminé, et puis il exécute en outre de codage. Si son travail d'une autre manière, je suis impatient de le savoir.
Semble trop compliqué, et le "pas le choix" allégation est fausse.
vous pouvez envisager d'utiliser fcntl pour définir
result.stdout
non bloquant, cela permettra de lire en temps réel et s'il n'existe pas encore de données, IOError
seront soulevéesOriginalL'auteur Niyojan | 2013-05-15
Vous devez vous connecter pour publier un commentaire.
Le problème ici est que
.readlines()
obtient la totalité de la sortie avant de revenir, comme il construit une liste complète. Juste itérer directement:for line in result.stdout
n'a pas de retour en "temps réel" sur Python 2, utilisezfor line in iter(result.stdout.readline, b'')
à la place (votreprint line
déclaration suggère que vous vous attendez à ce qu'il fonctionne sur Python 2. Sur Python 3, il fonctionne très bienOui, son travail, je suis sortie en temps réel, je vous Remercie.
OriginalL'auteur Eric
.readlines()
renvoie une liste de tous les lignes du processus de retour lorsqu'il est ouvert, c'est à dire, il ne retourne rien, jusqu'à ce que tous de sortie de la sous-processus est reçu. Pour lire ligne par ligne en "temps réel":Remarque: si le sous-processus utilise le bloc-tampon lorsqu'il est exécuté en mode non-interactif; vous pourriez avoir besoin
pexpect
,pty
modules oustdbuf
,annuler les tampons
,script
commandes.Remarque: sur Python 2, vous pourriez aussi avoir besoin d'utiliser
iter()
, pour obtenir le "temps réel" de sortie:OriginalL'auteur jfs
Vous pouvez effectuer une itération sur les lignes une par une en utilisant
readline
sur le tuyau:Les lignes contiennent une fuite
\n
qui je l'ai démonté pour l'impression.Lorsque le processus se termine, readline retourne une chaîne vide, de sorte que vous savez quand vous arrêter.
avez-vous essayé? Vous êtes à l'aide de
readlines
, qui renvoie toutes les lignes. C'est seulement possible après la résiliation. Avecreadline
, vous obtenez seulement la prochainerésultat.stdout fonctionne très bien pour moi, mais votre ligne.bande de fonctions() est utile comme je l'ai été d'avoir trop de "b" \r\n" " avant, Merci
OriginalL'auteur Thomas Fenzl