IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

pty.openpty() / subprocess.Popen() / Problème read/write [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    251
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 251
    Par défaut pty.openpty() / subprocess.Popen() / Problème read/write
    Bonjour,

    La commande :
    python3 /opt/app-root/lib/python3.9/site-packages/ATL/TestRunner.py --config=E2E/Global/AUTOTEST1.tsdef

    Affiche :
    Connect BRTE500 on connector J21
    yes ?


    (je dois répondre par "yes" pour continuer)

    J'ai réalisé un script pour lancer plusieurs commandes comme celle-ci à la suite.

    Mon soucis du moment est que je dois répondre "yes" chaque fois que la réponse est "yes ?".

    Je me permets de vous présenter mon premier jet mais ce script semble avoir un problème car je ne lis jamais le premier "yes ?"
    Il affiche :
    Affiche et reste bloqué sur :
    Connect BRTE500 on connector J21

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    import pty
    import os
    import subprocess
     
    def run_atl_test_runner():
        command = [
            "python3",
            "/opt/app-root/lib/python3.9/site-packages/ATL/TestRunner.py",
            "--config=E2E/Global/AUTOTEST1.tsdef"
        ]
     
        try:
            master, slave = pty.openpty()  # Création du pseudo-terminal
            process = subprocess.Popen(
                command,
                stdin=slave,
                stdout=slave,
                stderr=subprocess.PIPE,
                text=True,
            )
            os.close(slave)
     
            while True:
                output = os.read(master, 2048).decode()  # Lire la sortie
                print(output, end="")  # Afficher la sortie
                if "yes ?" in output:
                    os.write(master, "yes\n")  # Envoyer "yes" en réponse
        except Exception as e:
            print(f"An error occurred: {e}")
     
    if __name__ == "__main__":
        run_atl_test_runner()
    En vous remerciant d'avoir lu jusque là.

    Michel

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par Michelk12 Voir le message
    En vous remerciant d'avoir lu jusque là.
    Utiliser subprocess et des ptys n'est pas un activité de débutant.

    Si on débute dans l'utilisation de ces fonctionnalités, on cherche (sur Internet) à comprendre comment fonctionne un exemple qui marche puis on cherche à l'adapter.

    Et si on se retrouve à demander de l'aide, on poste un exemple de code qui pourra être reproduit facilement.

    Après on peut lire votre prose et se poser des tas de questions notamment sur l'intérêt de la ligne 22 (entre autre).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Michelk12 Voir le message
    Mon soucis du moment est que je dois répondre "yes" chaque fois que la réponse est "yes ?".

    Je me permets de vous présenter mon premier jet mais ce script semble avoir un problème car je ne lis jamais le premier "yes ?"
    Je ne connais pas le module pty (je suis en train de regarder la doc) mais déjà il y a divers trucs qui me gênent
    1. si ton process prend son stdin dans slave, pourquoi tu écris "yes" dans master ?
    2. si tu lis le message depuis master pourquoi le process écrit ses sorties dans slave ?
    3. pourquoi tu renvoies les erreurs dans un pipe et où va ce pipe ?

    Bon peut-être que la doc me dira mieux ce que représentent "master" et "slave" et que certaines questions tomberont d'elle-même. Quoi qu'il en soit, vis à vis de Python pur, checker les erreurs c'est vraiment checker les erreurs. On ne benne pas son code dans "Exception" en se disant "comme ça je suis tranquille" parce que justement ça masque toutes les erreurs (y compris les erreurs de logique) et tu ne vois pas ce qui ne va pas. De plus on ne met dans le try que la commande (ou au pire les 2/3 commandes) qui peuvent provoquer l'erreur et non pas le tout car justement quand on a une erreur on ne sait pas/plus de quelle instruction elle provient. Et enfin os.write() veut du bytes et pas du str.

    Je viens de tenter un code ressemblant au tien mais un peu plus simple à base de "rm -i fichier" et mon test a fonctionné (il a bien lu le "yes"). Accessoirement le message interrogatif du "rm" passe par stderr et non stdout.

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import pty
    import os
    import subprocess
     
    def run_atl_test_runner():
    	command = (
    		"rm",
    		"-i",
    		"passwd",
    	)
     
    	(master, slave) = pty.openpty()  # Création du pseudo-terminal
    	process = subprocess.Popen(
    		command,
    		stdin=master,
    		#stdout=master,
    		stderr=master,
    		text=True,
    	)
    	output = os.read(master, 2048).decode("utf-8")
    	print("[%s]" % output)  # Afficher la sortie
    	if "protégé" in output:
    		os.write(master, "yes".encode("utf-8"))
     
    if __name__ == "__main__":
    	run_atl_test_runner()
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 065
    Par défaut
    Hello,

    pexpect est spécifiquement conçu pour gérer des dialogues interactifs où un processus attend une entrée utilisateur en fonction de la sortie affichée.

    Pourquoi s'embêter avec subprocess qui oblige à,
    • lire manuellement les données de sortie.
    • parcourir ou rechercher les correspondances.
    • implémenter ses propres temporisations.


    Le seul inconvénient de ce module c'est sur Windows, il faut utiliser pexpect.popen_spawn.PopenSpawn qui s'appuie sur subprocess.Popen et donc qui le rend moins natif.

    Mais au moins on réinvente pas la roue, surtout si ces mécanismes (comme la synchronisation entre lecture et écriture) ne sont pas maîtrisés.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Mais au moins on réinvente pas la roue, surtout si ces mécanismes (comme la synchronisation entre lecture et écriture) ne sont pas maîtrisés.
    La question était: pourquoi que je ne récupère pas "Yes?" avec une lecture bourrin...
    On peut changer de canasson: pexpect utilise des pty et autres sous process en le masquant sous sa couche d'abstraction. Mais il faudra quand même lire la documentation et apprendre à l'utiliser pour en tirer profit...
    Du coup on revient au problème de départ: comment utiliser un module qu'on connaît peu.

    Citation Envoyé par Sve@r Voir le message
    Je viens de tenter un code ressemblant au tien mais un peu plus simple à base de "rm -i fichier" et mon test a fonctionné (il a bien lu le "yes").
    On essaie de reproduire le problème avec le code fournit...
    Si on part avec une autre commande externe... quel est l'intérêt de tout réécrire pour constater qu'on ne reproduit rien?

    Puis quel est l'intérêt de dire:
    Citation Envoyé par Sve@r Voir le message
    Quoi qu'il en soit, vis à vis de Python pur, checker les erreurs c'est vraiment checker les erreurs. On ne benne pas son code dans "Exception" en se disant "comme ça je suis tranquille"
    alors que le PO précise qu'il s'agit de son premier jet et qu'il n'a pas écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        ....
    except:
        pass
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
       ...
    except Exception as e:
       print (e)
    Dans un premier jet, voir ce qui en sort avant de décider de quoi gérer est raisonnable.
    Pourquoi monter sur ses grands chevaux, pour quelque chose sans rapport avec la question posée?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 547
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 547
    Par défaut
    moi, je me demande si on ne peut pas forcer la connexion par un paramètre sur le lancement de testrunner.py (comme on (je) n'ai aucune idée de ce que ce script contient, je ne saurais dire si c'est possible ou pas)

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    La question était: pourquoi que je ne récupère pas "Yes?" avec une lecture bourrin...
    Oui enfin quand on a un minimum d'intuition, on en déduit qu'elle se prolonge implicitement par : et comment puis-je faire pour récupérer "yes?" ou toute autre question posée par la commande...

    Citation Envoyé par wiztricks Voir le message
    On essaie de reproduire le problème avec le code fournit...
    Avec un code qui fait appel à un programme "TestRunner" qu'on n'a pas ? Oui pourquoi pas...

    Citation Envoyé par wiztricks Voir le message
    Si on part avec une autre commande externe... quel est l'intérêt de tout réécrire pour constater qu'on ne reproduit rien?
    Tu veux reproduire le problème ? Si ça te fait plaisir... Moi je préfère montrer qu'on peut produire une solution au problème (à savoir lire la question posée par une commande, l'analyser un minimum, et lui envoyer la réponse qu'elle attend).

    Citation Envoyé par wiztricks Voir le message
    Dans un premier jet, voir ce qui en sort avant de décider de quoi gérer est raisonnable.
    Voir ce qui en sort oui, Donc regarder les exceptions levées avant de vouloir les traiter. A la limite mettre print(e, type(e)) à la limite...

    Citation Envoyé par wiztricks Voir le message
    Citation Envoyé par wiztricks Voir le message
    Utiliser subprocess et des ptys n'est pas un activité de débutant.

    Si on débute dans l'utilisation de ces fonctionnalités, on cherche (sur Internet) à comprendre comment fonctionne un exemple qui marche puis on cherche à l'adapter.

    Et si on se retrouve à demander de l'aide, on poste un exemple de code qui pourra être reproduit facilement.

    Après on peut lire votre prose et se poser des tas de questions notamment sur l'intérêt de la ligne 22 (entre autre).
    Pourquoi monter sur ses grands chevaux, pour quelque chose sans rapport avec la question posée?

    C'est l'hôpital qui se fout de la charité !!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 065
    Par défaut
    Hello,

    @wiztricks,

    La question était: pourquoi que je ne récupère pas "Yes?" avec une lecture bourrin...
    Euh je l'ai expliqué, c'est pourquoi je propose pexpect qui évite de réinventer la roue.

    On peut changer de canasson: pexpect utilise des pty et autres sous process en le masquant sous sa couche d'abstraction. Mais il faudra quand même lire la documentation et apprendre à l'utiliser pour en tirer profit...
    Mieux vaut lire une documentation que 4, c'est déjà un gain de temps énorme, y compris dans le code à développer.

    Du coup on revient au problème de départ: comment utiliser un module qu'on connaît peu.
    Lire la doc de subprocess ne suffit pas justement, alors que pexpect oui.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    251
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 251
    Par défaut
    Désolé, j'ai travaillé sur autres tâches prioritaires.

    J'ai écris ce magnifique script dans un fichier nommé "mon_script_interactif.py"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import time
     
    print("Pour test script interactif", flush=True)
    time.sleep(1)
     
    for i in range(4):
        print("Continuons-nous ?")
        response = input("oui ? ")
        if response.lower() == "oui":
            print(f"Continuons ({i}) ...", flush=True)
            time.sleep(1)
        else:
            print("Réponse invalide", flush=True)
            break
    Manuellement, exécutant python3 mon_script_interactif.py :
    Pour test script interactif
    Continuons-nous ?
    oui ? oui
    Continuons (0) ...
    Continuons-nous ?
    oui ? oui
    Continuons (1) ...
    Continuons-nous ?
    oui ? oui
    Continuons (2) ...
    Continuons-nous ?
    oui ? oui
    Continuons (3) ...



    Avec le peu que j'ai lu sur pexpect, petit test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import pexpect
    import sys
     
    x = pexpect.spawn("python3 mon_script_interactif.py",  encoding='utf-8')
    x.logfile = sys.stdout
     
     
    x.expect("oui ?")
    x.sendline("oui")
     
    x.expect("oui ?")
    x.sendline("oui")
    C'est bizarre :
    Pour test script interactif
    Continuons-nous ?
    oui ? oui
    oui
    Continuons (0) ...
    oui

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 065
    Par défaut
    À tester,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import pexpect
     
    def run_atl_test_runner():
        command = (
            "python3 /opt/app-root/lib/python3.9/site-packages/ATL/TestRunner.py "
            "--config=E2E/Global/AUTOTEST1.tsdef"
        )
        try:
            process = pexpect.spawn(command, encoding="utf-8", timeout=None)
     
            while True:
                line = process.readline()
                if not line:
                    break
     
                print(line, end="")
     
                if "yes ?" in line:
                    print("Sending 'yes' as response...")
                    process.sendline("yes")
     
        except pexpect.EOF:
            print("Process finished.")
        except Exception as e:
            print(f"An unexpected error occurred: {e}")
     
    run_atl_test_runner()

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    251
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 251
    Par défaut
    Merci Fred,

    J'ai ajouté "logfile=sys.stdout" à la fonction spawn().

    Et avec ce code, cela n'affiche que :

    Connect BRTE500 on connector J21
    yes ? Connect BRTE500 on connector J21


    Idem avec mon petit script de test :
    Pour test script interactif
    Pour test script interactif
    Continuons-nous ?
    Continuons-nous ?
    oui ?

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    251
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 251
    Par défaut
    Avec mon script de test ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import sys
    import pexpect
     
    def run_atl_test_runner():
        command = "python3 mon_script_interactif.py"
        try:
            process = pexpect.spawn(command, encoding="utf-8", timeout=None, logfile=sys.stdout)
     
            while True:
                process.expect("oui ?")
                process.sendline("oui")
     
        except pexpect.EOF:
            print("Process finished.")
        except Exception as e:
            print(f"An unexpected error occurred: {e}")
     
    run_atl_test_runner()
    Donne :

    Pour test script interactif
    Continuons-nous ?
    oui ? oui
    oui
    Continuons (0) ...
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    Continuons-nous ?
    oui ? Continuons (1) ...
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    Continuons-nous ?
    oui ? Continuons (2) ...
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    oui
    Continuons-nous ?
    oui ? Continuons (3) ...
    oui
    oui
    etc.


    Alors comment réaliser le sendline uniquement si expected ?

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    251
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 251
    Par défaut
    Avec mon petit script pour test, ce code fonctionne enfin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import sys
    import pexpect
     
    def run_atl_test_runner():
        # command = "python3 /opt/app-root/lib/python3.9/site-packages/spherea/utest/ATL/ATLTestRunner.py --config=E2E/Global/AUTOTEST-IBOX_3.tsdef"
        command = "python3 mon_script_interactif.py"
        try:
            process = pexpect.spawn(command, encoding="utf-8", timeout=None, logfile=sys.stdout)
            process.setecho(False)  # Empêche l'écho des lignes envoyées
     
            while True:
                match_index = process.expect(["oui ?", "Continuons-nous ?", pexpect.EOF, pexpect.TIMEOUT])
     
                if match_index == 0:  # Motif "yes ?"
                    process.sendline("oui")
                    process.expect(["Continuons-nous ?", pexpect.EOF, pexpect.TIMEOUT])  # Attendre la suite
                elif match_index == 1:  # Nouveau cycle de question
                    print("Motif 'Continuons-nous ?' détecté. Attente de l'invite suivante.")
                elif match_index == 2:  # Fin du processus
                    print("Processus terminé.")
                    break
                elif match_index == 3:  # Timeout
                    print("Timeout atteint. Vérifiez le processus.")
                    break
     
        except pexpect.EOF:
            print("Fin de la sortie du processus.")
        except Exception as e:
            print(f"Une erreur inattendue est survenue : {e}")
     
    if __name__ == "__main__":
        run_atl_test_runner()
    Affiche :
    Pour test script interactif
    Continuons-nous ?
    Motif 'Continuons-nous ?' détecté. Attente de l'invite suivante.
    oui ? oui
    Continuons (0) ...
    Continuons-nous ?
    oui ? oui
    Continuons (1) ...
    Continuons-nous ?
    oui ? oui
    Continuons (2) ...
    Continuons-nous ?
    oui ? oui
    Continuons (3) ...
    Processus terminé.


    Je vais voir pour l'adapter à mon cas réel...

  14. #14
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par Michelk12 Voir le message
    Alors comment réaliser le sendline uniquement si expected ?
    Si vous changez de techno, vous êtes supposé avoir pris le temps d'ouvrir un tuto pour apprendre à l'utiliser avant de demander de l'aide... .et ouvrir une nouvelle discussion puisque ce n'est plus le même sujet.

    Pour ce qui est du code initial, en corrigeant les 2 boulettes signalées, ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    import pty
    import os
    import subprocess
     
    command = [
        "python3",
        "zzz.py",
    ]
     
    try:
        master, slave = pty.openpty()  # Création du pseudo-terminal
        process = subprocess.Popen(
            command,
            stdin=slave,
            stdout=slave,
            stderr=slave,
            shell=True,
        )
        #os.close(slave)
        while True:
            output = os.read(master, 2048).decode()  # Lire la sortie
            print(output, end="")  # Afficher la sortie
            if "yes?" in output:
                os.write(master, "yes\n")  # Envoyer "yes" en réponse
            else:
                break
    except Exception as e:
        print(f"An error occurred: {e}")
    avec zzz.py:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while True:
        a = input('yes?')
        if a.lower() != 'yes':
            break
    Citation Envoyé par Sve@r Voir le message
    Tu veux reproduire le problème ? Si ça te fait plaisir... Moi je préfère montrer qu'on peut produire une solution au problème (à savoir lire la question posée par une commande, l'analyser un minimum, et lui envoyer la réponse qu'elle attend).
    C'est fait: juste pour montrer que reproduire le problème et/ou comprendre les soucis du code proposé par le PO plutôt que de tout jeter et en pondre un autre vite fait alors qu'il y a déjà plein de tuto sur Internet: les pty sont une techno qui existait déja en 82!
    On arrive à un code "fonctionnel" ezn s'appliquant à coller a ce qui a été fait.

    Mais comme prévu le PO n'en a rien à foutre d'apprendre, il veut juste un truc qui marche sans trop avoir à se prendre la tête (raison pour laquelle je ne me fatigue plus trop à coder ici: faire du prêt à emporter pour ceux qui ne veulent pas faire chauffer leurs neurones? chatGPT est bien meilleur que moi!)

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    251
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 251
    Par défaut
    Me revoilà avec une version qui fonctionne, je comprends mieux du coup le fonctionnement du module pexpect.
    J'ai même bouclé pour automatiser TEST1, 2, 3, etc. et aucun soucis.
    Je tiens enfin à tous vous remercier, très sincèrement. En général, je code seul et cela me fait plaisir d'avoir obtenu de l'aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
        command = "python3 /opt/app-root/lib/python3.9/site-packages/ATL/TestRunner.py --config=E2E/Global/AUTOTEST1.tsdef"
        try:
            process = pexpect.spawn(command, encoding="utf-8", timeout=None, logfile=sys.stdout)
            process.setecho(False)  # Empêche l'écho des lignes envoyées
     
            while True:
                match_index = process.expect(["yes ?", "Running...", pexpect.EOF, pexpect.TIMEOUT])
     
                if match_index == 0:  # Motif "yes ?"
                    process.sendline("yes")
                    process.expect(["Running...", pexpect.EOF, pexpect.TIMEOUT])  # Attendre la suite
                elif match_index == 1:  # Nouveau cycle de question
                    print("Motif 'Running...' détecté. Attente de l'invite suivante.")
                elif match_index == 2:  # Fin du processus
                    print("Processus terminé.")
                    break
                elif match_index == 3:  # Timeout
                    print("Timeout atteint. Vérifiez le processus.")
                    break
        except pexpect.EOF:
            print("Fin de la sortie du processus.")
        except Exception as e:
            print(f"Une erreur inattendue est survenue : {e}")

  16. #16
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 065
    Par défaut
    Je ne connais pas expect non plus, faudrait analyser avec un debugger et faire des tests,

    Dernier essai,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import pexpect
    import sys
     
    def run_atl_test_runner():
        command = "python3 /opt/app-root/lib/python3.9/site-packages/ATL/TestRunner.py --config=E2E/Global/AUTOTEST1.tsdef"
        process = pexpect.spawn(command, encoding='utf-8', logfile=sys.stdout)
     
        try:
            process.expect("yes ?")
            print("Prompt detected. Sending 'yes'...")
            process.sendline("yes")
     
            process.expect(pexpect.EOF)
            print("Process completed.")
     
        except pexpect.exceptions.EOF:
            print("The process finished unexpectedly.")
        except pexpect.exceptions.TIMEOUT:
            print("Timeout occurred while waiting for output.")
     
     
    run_atl_test_runner()

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Read - write
    Par Ladgalen dans le forum Débuter
    Réponses: 3
    Dernier message: 12/05/2008, 17h36
  2. [MASM32][Débutant] Read / Write Console
    Par Jean Michou dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 16/04/2008, 23h24
  3. probleme read write serveur/client
    Par romainromain dans le forum Réseau
    Réponses: 9
    Dernier message: 22/11/2006, 16h23
  4. propriété read write
    Par new_wave dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 08/09/2006, 11h24
  5. Problème de read/write
    Par mylooz dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 25/03/2005, 19h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo