Partage
  • Partager sur Facebook
  • Partager sur Twitter

Relancer une applications python

Sujet résolu
    4 mars 2013 à 13:02:35

    Bonjour,

    J'aimerais savoir s'il est possible de relancer une application Python, avec la même ligne de commande que celle qui a lancé l'applis en cours. Par exemple sur un test if, je relance le main en fonction du résultat du test, et toutes les données sont réinitialisées totalement comme si c'était la première fois que je lance main.

    C'est assez clair ?

    Merci

    • Partager sur Facebook
    • Partager sur Twitter
      4 mars 2013 à 13:07:36

      Je ne suis pas sûr d'avoir bien compris. Tu veux relancer la même commande python avec les mêmes arguments ?

      Si c'est ça tu peux récupérer les arguments avec sys.argv. Sinon je t'invite à éclaicir ta question.

      • Partager sur Facebook
      • Partager sur Twitter
      Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
        4 mars 2013 à 13:13:04

        Oui en gros c'est ça, et je veux aussi quitter complètement l'appli en cours. C'est un peu comme si dans un terminal je fais Ctrl+C puis relance la dernière commande. Sauf que là c'est l'appli qui se quitte et relance une ligne de commande.

        D'un point de vue terminal, cela donnerais en lançant une seule ligne de commande.

        $ ./main.py arg1 arg2
        ## Display of main.py
        ...
        ## Erreur, le programme se relance automatiquement, l'appli quitte
        $ ./main.py arg1 arg2
        ...



        • Partager sur Facebook
        • Partager sur Twitter
          4 mars 2013 à 13:33:24

          Dans ce cas je pense que ce qui t'intéresse est la fonction exec*().

          • Partager sur Facebook
          • Partager sur Twitter
          Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
            4 mars 2013 à 15:32:31

            A première vue ça me semble pas mal mais il y a cette phrase qui me laisse septique.

             On Unix, the new executable is loaded into the current process, and will have the same process id as the caller.


            Idéalement il faudrait que le nouvel exécutable soit indépendant du premier. Comme ça j'utilise exec*(), puis ferme mon premier process (dans l'idée c'est ce que j'aimerais, mais là je pense que tout se fermerait).

            Je me dis éventuellement utiliser un démon, mais c'est surement pas adapté ? Si jamais j'ai trouvé ça : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

            • Partager sur Facebook
            • Partager sur Twitter
              4 mars 2013 à 15:36:57

              Pourquoi veux tu que le nouvel exécutable soit "indépendant" du premier puisque tu fermes l'autre ?

              Enfin si tu y tiens vraiment regarde spawn(), ça fait la même chose qu'exec mais ça te permet de détâcher le processus.

              • Partager sur Facebook
              • Partager sur Twitter
              Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
                4 mars 2013 à 16:05:12

                Je veux qu'il soit indépendant pour fermer le premier justement. Si ils ne sont pas indépendant, en fermant le premier ça risque de fermer le 2ème non ?

                Bon le moment des tests est venu, je vais tester toutes ces fonctions. spawn() semble mieux adapté à ma demande.

                Merci

                • Partager sur Facebook
                • Partager sur Twitter
                  4 mars 2013 à 16:27:59

                  Mais le premier se "ferme" automatiquement puisqu'il est remplacé par l'autre. Je ne comprends pas ta logique là. À moins que tu ne veuilles le faire tourner en arrière plan. Dans ce cas oui, il vaut mieux faut utiliser spawn.

                  -
                  Edité par PyTony 4 mars 2013 à 16:28:26

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
                    4 mars 2013 à 16:39:00

                    Hmm, je ne suis pas sur que le coup du spawn avec P_DETACH soit vraiment ce que tu veux faire. Ça va détacher le processus fils de la CONSOLE du processus père, donc tu risques de ne pas récupérer sa sortie.

                    Avec un execve, si le père n'est pas quitté, au moins tu gardes le contrôle sur ce que fait le fils et le prompt du shell ne revient pas avant la fin de l'exécution du fils.

                    Dans tous les cas, si tu crées un processus fils et que tu tues le père sans attendre la terminaison du fils, tu crées un orphelin qui deviendra un zombie lorsqu'il aura terminé son exécution.

                    -
                    Edité par nohar 4 mars 2013 à 16:42:38

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Zeste de Savoir, le site qui en a dans le citron !
                      4 mars 2013 à 16:55:32

                      Beurk un orphelin zombie ça doit pas être beau à voir :p

                      Mais, nohar, avec les fonctions exec*(), il n'y a pas de raison que ça arrive, puisque le processus courrant est remplacé par le nouveau, non?

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
                        4 mars 2013 à 17:39:45

                        Oui, voilà.

                        C'est pour ça qu'à mon avis il vaut mieux utiliser exec*, ou un subprocess avec un "wait()", plutôt que de créer un processus indépendant qui va faire sa vie dans son coin.

                        -
                        Edité par nohar 4 mars 2013 à 17:41:31

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Zeste de Savoir, le site qui en a dans le citron !
                          5 mars 2013 à 10:54:24

                          Je pense que je vais partir sur exec* car spawn* ne me donne pas accès au stdin en effet.
                          J'ai lu que le 'e' permet de mapper l'environnement du père avec celui du fils. Dans mon cas je veux un tout nouvel environnement. Donc je vais partir sur l'utilisation de execv() je pense.

                          Il me reste à faire les tests pour voir comment se quitte le père. Apparemment, le fils prend la place du père, c'est à dire que le père ne poursuivra jamais son exécution ! Ça me semble bien résoudre mon problème ça.

                          Voici le code que j'ai fait pour tester

                          #!/usr/bin/python
                          # -*- coding:UTF-8 -*-
                          """
                          This module test the way to relaunch a script independant from the parent.
                          """
                          import os
                          import sys
                          import time
                          
                          def action1( a = 1 ):  
                              
                              print "Action1 : %d"%(a)
                              time.sleep(1)
                              return 0
                          
                          def action2( a = 2 ):
                              
                              i = 0
                              try:
                                  while(1):
                                      print "Action2 - i=%d: %d"%(i,a)
                                      i += 1 
                                      time.sleep(1)
                              except KeyboardInterrupt:
                                  print "Action 2 exiting"
                                  return 0
                          
                          def action3( a = 3 ):
                              
                              try:
                                  a = input('Please enter a number')
                              except:
                                  print("Bad input, a set to 0")
                                  a = 0
                              print "Action3 : %d"%a
                              return 0
                          
                          
                          if __name__ == '__main__':
                              
                              # Catch comment line arguments
                              nb_arg = len(sys.argv) - 1
                          
                              if nb_arg == 0:
                                  print "Please enter argument"
                                  exit()
                          
                              action2( int(sys.argv[1]) )
                          
                              # Launch the new appli
                              if 'relaunched' not in sys.argv:
                                  print "Launched the child process"
                                  os.execv(sys.argv[0], [sys.argv[0], str(int(sys.argv[1])+1),'relaunched'] )
                                  print "The child exited"
                              
                              if 'relaunched' not in sys.argv:
                                  print "The parent is running"
                              else:
                                  print "The child is running"
                          
                              print "The parent is exiting : " + str( 'relaunched' in sys.argv )
                              sys.exit()
                          



                          -
                          Edité par FloOows 5 mars 2013 à 11:12:35

                          • Partager sur Facebook
                          • Partager sur Twitter
                            5 mars 2013 à 11:03:55

                            Euh non, normalement le père ne reprend pas son exécution après. Une fois qu'on est rentré dans le fils, il n'y a plus moyen de retrouver la trace du père.

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
                              5 mars 2013 à 11:52:26

                              PyTony a écrit:

                              Euh non, normalement le père ne reprend pas son exécution après. Une fois qu'on est rentré dans le fils, il n'y a plus moyen de retrouver la trace du père.

                              Oui c'est ce qu'il me fallait, j'avais peur que ce ne soit pas le cas mais du coup c'est bon.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                5 mars 2013 à 12:01:02

                                Flows a écrit:

                                PyTony a écrit:

                                Euh non, normalement le père ne reprend pas son exécution après. Une fois qu'on est rentré dans le fils, il n'y a plus moyen de retrouver la trace du père.

                                Oui c'est ce qu'il me fallait, j'avais peur que ce ne soit pas le cas mais du coup c'est bon.

                                Il faut tester avant de prendre des précautions inutiles. :p (et de poser la question :-° )

                                -
                                Edité par PyTony 5 mars 2013 à 12:02:11

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Envie de mettre les mains dans le cambouis ? Passez à Funtoo GNU/Linux. DO IT!
                                  5 mars 2013 à 12:53:05

                                  PyTony a écrit:

                                  Il faut tester avant de prendre des précautions inutiles. :p (et de poser la question :-° )

                                  Tu as raison. C'est pour ça que j'ai édité mon message après avoir posé la question, mais tu as peut être lu la première version de mon message qui en effet est arrivée avant les tests.



                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    5 mars 2013 à 12:55:59

                                    Par contre :

                                    Flows a écrit:

                                    J'ai lu que le 'e' permet de mapper l'environnement du père avec celui du fils. Dans mon cas je veux un tout nouvel environnement.

                                    Tu ne crées pas "un tout nouvel environnement" en utilisant execv, mais tu appelles le fils avec un environnement vide. Quoiqu'il en soit je doute que tu aies bien compris de quoi il s'agit : l'environnement d'exécution, c'est l'ensemble de variables définies au-dessus des processus, (comme la variable PATH, par exemple, ou HOME). Si tu lances deux processus dans un même terminal, ils auront le même environnement. Donc dans ton exemple ce n'est absolument pas un problème si le fils se lance avec le même environnement que le père.

                                    Cela dit, c'est quand même mieux de ne pas passer l'environnement au nouveau processus créé si tu n'en as pas expressément besoin, parce que dans certains cas ça peut se révéler être une faille de sécurité (quoique moins directement avec exec() qu'avec system()).

                                    -
                                    Edité par nohar 5 mars 2013 à 12:57:06

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Zeste de Savoir, le site qui en a dans le citron !
                                      5 mars 2013 à 14:28:07

                                      Merci pour cette précision, en effet je ne l'avais compris comme ça.
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Relancer une applications python

                                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                      • Editeur
                                      • Markdown