Probleme passage d'argument shell unix -> py

Bonjour,
j'ai un problème pour passer des arguments d'un shell Unix à un script python.
Voici mon problème :
Dans le shell unix :
$A="toto"
$B="deux mots"
./jpython prog.py "$A" "$B"

Dans le code python je récupère les infos suivantes :
print sys.argv[0] # affiche "prog"
print sys.argv[1] # affiche "toto"
print sys.argv[2] # affiche "deux"
print sys.argv[3] # affiche "mots"

Je voudrais savoir comment récupérer "deux" et "mots" dans le même argument.

J'ai essayé de passer la chaine "deux mots" entre '', mais rien n'y fait, car je récupère
print sys.argv[2] # affiche "'deux"
print sys.argv[3] # affiche "mots'"

Est ce que quelqu'un a une solution ?

Merci d'avance

8 réponses

  1. faut pas mettre printf au lieu de print ?
    0
    1. Le problème ne vient pas du print (ou du printf qui n'existe pas à a conaissance en python) mais du contenu des variables, c'est à dire de l'interprétation des variables passées par le shell au scrit python.

      Pour l'instant, j'ai développé une bidouille interne au script python qui interprète le contenu des variables pour les recomposer si besoin, mais cela n'est pas fiable à 100%, alors si quelqu'un a une solution ...

      Magicjibus

      Merci quand même de cette contribution
      0
  2. Contributeur
    Salut,

    Le spécialiste Python du forum c'est SebSauvage ... devrait pas tarder.

    A+  K.
    It's going down ...
    0
    1. Modérateur
      Me vlà ! :-)

      Pour parser la ligne de commande, je te recommande vivement d'utiliser le module getopt.

      ça te permettra de récupérer correctement les noms de fichier comportant des espaces en argument.
      0
      1. Modérateur
        Ah oui tant que j'y pense:

        Unix ne supporte pas les noms de fichiers comportant des espaces :)
        0
        1. Merci, je vais essayé de voir du côté de getopt, mais à ma connaissance, cette fonction servait principalement à parser les options que l'on pouvait avoir en ligne de commande d'un script, et non à récupérer des paramètres.

          Et ne t'inquiètes pas, c'est pas pour des noms de fichiers que j'ai besoin d'espace dans mes paramètres ... ;-). C'est pour autre chose (un truc vachement important et secret alors ...).

          Merci de votre aide et @ plus.
          0
        2. Modérateur
          @Magicjibusok :-)

          En fait getopt est également très utile pour récupérer correctement les noms de fichiers passés en ligne de commande
          (il débrouille bien en particulier sur les chaînes quotées
          ex: python monprogramme.py "mon fichier1.doc" "mon fichier2.txt")
          0
        3. @MagicjibusArg, j'ai le meme probleme que Magicjibus, quelques années après..
          Ta solution me parait parfaite sebsauvage, mais je n'arrive pas a utiliser getopt pour faire cela.
          Pourrait tu m'indiquer les quelques lignes de code pour récuperer mon parametre
          ex : python monprogramme.py "mon parametre1" "mon parametre2"

          Merci.
          0
      2. Modérateur
        Exemples complets avec getopt et optparse:
        https://www.sebsauvage.net/python/snyppets/#parsing_cmdline
        0
        1. Merci pour cette explication tres claire sebsauvage.
          Mais dans tous les cas (utilisation de sys.argv[], getopt ou optparse), mon parametre entre quote est decoupé en deux parametre :
          "mon , et parametre"
          Comment faire pour que tout ce qui est entre quotes soit conservé, ou quel caractere peut etre utilisé pour remplacer cet espace.

          Mon but est en fait de passer une string utilisé en java, en parametre d'un appel a un script python.

          Merci pour votre aide.
          0
      3. Modérateur
        Tiens bizarre chez moi ça marche.

        Exemple:
        import optparse
        
        parser = optparse.OptionParser()
        (options, args) = parser.parse_args()
        print args


        Et je l'appelle:
        c:\data>python a.py "rcefce dcdc" "ba ba"
        ['rcefce dcdc', 'ba ba']


        Il me prend bien mes chaînes entre doubles-quotes.
        0
        1. Ok. Merci sebsauvage.
          En fait j'ai réussi a le faire marcher en ligne de commande, tu as raison, j'ai ce que je voulai..
          Mais lorsque j'appel avec mon code java :
          Process p = Runtime.getRuntime().exec(cmd)

          ou cmd est ma ligne de commande :
          String cmd = "python script.py \"deux mots\"";


          La seule reponse que j'obtien est :
          ['"deux', 'mots"']


          C'est bizare que le comportement ne soit pas le meme dans le terminal et dans mon programme java..

          Je vais essayer de chercher encore.
          Si quelqu'un peut m'aider.. merci
          0
      4. Modérateur
        Voilà l'explication:

        Quand tu fais exec() tu demande l'OS de lancer le programme. Mais ça ne passe pas par l'interpréteur de commande (cmd.exe) comme quand on le fait dans un fenêtre MS-Dos.

        Il faut donc faire:
        cmd = "cmd.exe /c python a.py \"deux mots\"";

        Et là ça marchera.

        (On lance l'interpréteur de command cmd et on lui demande de lancer le programme.)

        Attention: ça ne marchera que sous Windows NT/2000/XP/2003, pas sous les autres OS (95/98/ME, Linux...)
        0
        1. J'ai également ce problème d'espace mais je suis sous Linux et les caractères \ ne règlent pas le problème.
          De mon côté, j'ai un script shell (ayant ses propres arguments) qui appelle un programme python :
          python mon_prog.py $*
          Un affichage de $* me donne bien la chaîne voulu : -a "app yo" -d des -o pp
          mais par contre le programme python considère qu'il reçoit les arguments suivants :
          argv = ['mon_prog.py', '-a', '"app', 'yo"', '-d', 'des', '-o', 'pp']
          par contre quand je tape directement dans un terminal python mon_prog.py -a "app yo" -d des -o pp, aucun problème.
          Une idée comment résoudre ce problème sous Linux ?
          0
        2. @thalieAs-tu réussi à résoudre ce problème? Je suis dans le même cas j'ai essayé pas mal de truc et je trouve toujours pas une solution adequat.

          Merci
          0
      5. Ah ok, je vois le truc, pas bete !
        Le dernier probleme est que je développe sur Mac, depuis peu, donc je suis pas très habitué à l'environnement.
        Mais je pense arriver a trouver un équivalent.

        Merci bien
        0
        1. Salut!
          Il faut faire ceci:

          skami@skami-laptop:~/$python essay.py mdr ça\ marche\ avec\ ce\ système!
          1ère option:
          mdr
          2ème option:
          ça marche avec ce système!

          Quand on passe des argument il faut TOUJOURS remplacer les " " par des "\ "!
          C'est une des premières chose qu'on apprends :-°

          contenu de essay.py:

          #!/usr/bin/python
          # -*- coding:Utf-8 -*-
          import optparse

          parser = optparse.OptionParser()
          (options, args) = parser.parse_args()
          print "1ère option:"
          print "\t"+args[0]
          print "2ème option:"
          print '\t'+args[1]
          0