8
votes

Interagir avec une application de console Windows via Python

J'utilise Python 2.5 sous Windows. Je souhaite interagir avec un processus de console via Popen. J'ai actuellement ce petit extrait de code:

p = Popen( ["console_app.exe"], stdin=PIPE, stdout=PIPE )
# issue command 1...
p.stdin.write( 'command1\n' )
result1 = p.stdout.read() # <---- we never return here
# issue command 2...
p.stdin.write( 'command2\n' )
result2 = p.stdout.read()


2 commentaires

Votre code semble correct. La console_app fonctionne-t-elle correctement lorsque vous exécutez de la console? Qu'est-ce qu'il revient pour Command1?


OUI Console_App fonctionne normalement lors de l'exécution de CMD.exe, il suffit de produire certains numéros basés sur l'entrée fournie (et parfois des chaînes)


5 Réponses :


0
votes

Je pense que vous voudrez peut-être essayer d'utiliser readline () à la place?

EDIT: Désolé, MISSEXTOUD.

Peut-être Cette question peut vous aider?


1 commentaires

readline () est simplement suspendu. Je peux confirmer que l'application de la console fournit des données qui doivent être lues correctement sur le côté Python.



0
votes

est-il possible que l'application de la console ait soumoué sa sortie de manière à ce qu'il ne soit envoyé que sur stdout lorsque le tuyau est fermé? Si vous avez accès au code de l'application de la console, il est peut-être de coller une affleurement après que le lot de données de sortie pourrait aider?

Alternativement, est-ce que cela écrit réellement à stardr et au lieu de stdout pour une raison quelconque?

Je viens de regarder votre code à nouveau et pensé à autre chose, je vois que vous envoyez une "commande \ n". L'application Console pourrait-elle simplement attendre un caractère de retour de chariot au lieu d'une nouvelle ligne? Peut-être que l'application de la console vous attend de soumettre la commande avant de produire une sortie.


1 commentaires

Merci, bonnes suggestions. Malheureusement, je n'ai pas accès au code source de l'application de la console. A confirmé son écriture sur stdout et non stardr.



0
votes

avait exactement le même problème ici. J'ai creusé dans le code source DRPYTHON et a volé une solution wx.execute () , qui fonctionne bien, surtout si votre script utilise déjà WX. Je n'ai jamais trouvé la solution correcte sur la plate-forme Windows ...


0 commentaires

8
votes

Votre problème ici est que vous essayez de contrôler une application interactive.

stdout.read () continuera à lire jusqu'à ce qu'il atteigne la fin du flux, du fichier ou du tuyau. Malheureusement, dans le cas d'un programme interactif, le tuyau n'est que fermé que des sorties du programme; Ce qui n'est jamais, si la commande que vous avez envoyée était autre chose que "quitte" .

Vous devrez revenir à la lecture de la sortie de la ligne de sous-déprocession en utilisant stdout.readline () , et vous feriez mieux d'avoir un moyen de dire lorsque le programme est prêt à accepter une commande, et lorsque la commande que vous avez émise au programme est terminée et que vous pouvez fournir une nouvelle. une. Dans le cas d'un programme tel que cmd.exe , même readline () ne suffira pas car la ligne qui indique qu'une nouvelle commande peut être envoyée n'est pas terminée par une nouvelle ligne, Il faudra donc analyser l'octet d'octet de sortie. Voici un exemple de script qui exécute cmd.exe , recherche de l'invite, puis émet un dir , puis un Quitter : < Pré> xxx

Si le chronométrage n'est pas important et que l'interactivité d'un utilisateur n'est pas requise, il peut s'agir beaucoup plus simple de combiner les appels: xxx < / pré>


6 commentaires

Ça ne va pas fonctionner sous Windows comme laadead (1) bloque l'opération


Je sais que c'est pourquoi, après chaque octet, le script vérifie si l'invite est disponible et écrit la nouvelle commande avant de lire plus d'octets. Avez-vous même essayé le script? Ça marche.


Droite, je n'ai pas tapé ça à première vue. +1 Pour Nice, attendez-vous à la mise en œuvre.


Vous pouvez exclure également les invites de la sortie en faisant cela: "\ n" .join (CommandOutput.split ('\ r \ n') [1: -1])


En cas de cmd.exe , vous pouvez personnaliser l'invite pour faciliter le traitement. Par exemple, en utilisant cmd.exe / k. invite $ G $ G $ G $ _ changera l'invite à >>> \ n , de sorte que vous puissiez supprimer la correspondance des motifs et Utilisez readline () à nouveau.


@ Hurez cela devrait être une réponse séparée à la question



2
votes

Avez-vous essayé de forcer les lignes de fin de Windows? I.e.

p.stdin.write( 'command1 \r\n' )
p.stdout.readline()


0 commentaires