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 :

subprocess.Popen n'utilise pas le directory courant.Et pourquoi donc ?


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 304
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 304
    Par défaut subprocess.Popen n'utilise pas le directory courant.Et pourquoi donc ?
    Bonjour,

    Etrange comportement de subprocess.Popen

    Démonstration, je lance un appli graphique à partir de la console, je suis dans: "/home/vincent/PaQager"

    ~/PaQager$ python paqager.py
    Le code doit appeler un process non python qui exige un répertoire courant précis et différent de celui de l'appli. Chose très courante, en fait.

    Le 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
    19
     
    old_rep = os.getcwd()
    os.chdir(folder)
    cmd = ["dh_make", "-c", "gpl3", "-s"]
     
    print "Folder exist: ", folder, os.path.isdir(folder)
    print "Command: ", cmd, "\n"
     
    try:
         mk = subprocess.Popen(cmd, universal_newlines=True, 
                                    stdout=subprocess.PIPE).communicate()
         for r in mk[0].split("\n"):
              print "  ", r
     
    except OSError, why:
         print "Error :", why
     
    print "Done :"
    os.chdir(old_rep)
    Retours:
    Folder exist: /home/vincent/PaQager/examples/oqapy-0.4.0/oqapy-0.4.0 True
    Command: ['dh_make', '-c', 'gpl3', '-s']

    For dh_make to find the package name and version, the current directory
    needs to be in the format of <package>-<version>. Alternatively use the
    -p flag using the format <name>_<version> to override it.
    I cannot understand the directory name or you have an invalid directory name!

    Your current directory is /home/vincent/PaQager, perhaps you could try going to
    directory where the sources are?

    Please note that this change is necessary ONLY during the initial
    Debianization with dh_make. When building the package, dpkg-source
    will gracefully handle almost any upstream tarball.

    Done :
    J'ai toujours utiliser 'os.chdir(dir)' dans ces cas là, c'est bien la première fois que subprocess ne le prend pas en compte.

    Dans le code il n'y a aucune utilisation de 'dh_make' qui aurait put laisser penser à une variable fixée avant.

    J'ai tester 'os.system("cd %s" % folder)' à la place de 'os.chdir(dir)', sans succès.

    Autre exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    cmd = ["cd", folder, ";", "dh_make", "-c", "gpl3", "-s"]
     
    ou
    cmd = ["cd %s;" % folder, "dh_make", "-c", "gpl3", "-s"]
    est refusé, manifestement la commande "cd" ne passe pas.

    File "/usr/lib/python2.6/subprocess.py", line 480, in call
    return Popen(*popenargs, **kwargs).wait()
    File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)
    File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
    raise child_exception
    OSError: [Errno 2] Aucun fichier ou dossier de ce type
    Y compris en mettant le chemin en clair.

    C'est grave, docteur?

  2. #2
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Dans subprocess, tu peux setter cwd comme paramètre. Ça devrait t'aider. Et si tu lance ton script directement dans home/vincent/PaQager/examples/oqapy-0.4.0/oqapy-0.4.0 ?

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonsoir,

    Citation Envoyé par D[r]eadLock Voir le message
    Dans subprocess, tu peux setter cwd comme paramètre. Ça devrait t'aider. Et si tu lance ton script directement dans home/vincent/PaQager/examples/oqapy-0.4.0/oqapy-0.4.0 ?
    Citation Envoyé par VinsS Voir le message
    Autre exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    cmd = ["cd", folder, ";", "dh_make", "-c", "gpl3", "-s"]
     
    ou
    cmd = ["cd %s;" % folder, "dh_make", "-c", "gpl3", "-s"]
    est refusé, manifestement la commande "cd" ne passe pas.
    Est il besoin de rappeler que le chemin dans le script n'est pas le même que celui du système ?
    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
    patrice@Zeus:~$ pwd
    /home/patrice
    patrice@Zeus:~$ python
    Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
    [GCC 4.4.5] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os
    >>> os.chdir('/')
    >>> print os.listdir(os.getcwd())
    ['selinux', 'bin', 'lost+found', 'srv', 'database', 'dev', 'sys', 'proc', 'sbin', 'var', 'initrd.img', '.dpkg-old', 'media', 'opt', 'initrd.img.old', 'tmp', 'lib', 'cdrom', 'boot', 'home', 'root', 'usr', 'vmlinuz.old', 'mnt', 'etc', 'vmlinuz', 'xorg.conf.new']
    >>> print os.getcwd()
    /
    >>> quit()
    patrice@Zeus:~$ pwd
    /home/patrice
    Bon code

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    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 695
    Par défaut
    Salut PauseKawa,

    Normalement les fils créés via fork héritent des chdir faits par le parent seule un fork via execve devrait permettre de transférer le répertoire courant du shell.
    Popen propose la clé cwd à la création pour forcer le changement de répertoire courant.
    i.e. Popen (cwd=os.getcwd(),... ) devrait faire l'affaire mais il est tard pour aller regarder ce que ca fait dans les sources.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 304
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 304
    Par défaut
    Hélas, rajouter cwd=folder n'y changeait rien.

    En fait, je constate que le net abonde de posts au sujet de cette question.

    J'ai décidé de courageusement contourner le problème en appliquant la solution de Dreadloks.

    Comme mon appli est censée être installée dans /usr/share et le dossier traité par dh_make est, lui dans /home/user/..., l'appli copie dans ce dossier un petit script python qui exécute le subprocess à son tour.

    A noter que si je lance ce petit script avec subprocess aussi, ça ne marche pas, dh_make me répond toujours que je suis dans le directory de l'application principale.

    Avec os.system(cmd) par contre ça fonctionne.

    Merci

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    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 695
    Par défaut
    Salut,

    Citation Envoyé par VinsS Voir le message
    Avec os.system(cmd) par contre ça fonctionne.
    Une des différences entre os.system et Popen de base est le shell=True à ajouter dans le Popen pour encapsuler l'exécution dans un contexte shell
    - plutôt que d'exécuter directement la commande-.
    Note: C'est ce qui explique les comportements des "Autres exemples".

    L'option cwd (de Popen) fait la même chose que chdir, i.e. il change le répertoire 'avant' de créer le fils. C'était une fausse bonne idée.

    Si ça fonctionne avec os.system, cela devrait aussi fonctionner avec l'équvalent Popen(shell=True)).
    Probable dans ce cas que dh_make récupère la valeur d'une variable positionnée par le shell telle que PWD plutôt que via un appel C direct - le vrai -.

    Illustration
    >> import os, subprocess
    >> os.chdir('../')
    >> # sans shell il faut présenter les paramètres dans une liste,
    >> # ca invoque directement python
    >> subprocess.Popen(['python', '-c', 'import os; print os.getenv("PWD"') ])
    >> ### le répertoire affiché n'a pas du changer
    >> subprocess.Popen('pwd')
    >> ## affiche le répertoire cohérent avec chdir.

    shell=True ou os.system crée un shell pour lancer la commande dedans. L'effet de bord est de mettre à jour les variables d'environnements et non de les hériter directement du père.

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

Discussions similaires

  1. Utilisation de os.system ou subprocess.Popen
    Par othke dans le forum Général Python
    Réponses: 8
    Dernier message: 28/09/2011, 12h05
  2. Cas d'utilisation -> pas de découpage fonctionnel
    Par ribz33 dans le forum Cas d'utilisation
    Réponses: 13
    Dernier message: 25/08/2006, 16h26
  3. Réponses: 7
    Dernier message: 16/06/2006, 14h55
  4. Réponses: 1
    Dernier message: 15/05/2006, 12h28
  5. Oracle n'utilise pas tous mes CPUS
    Par noumayoss dans le forum Oracle
    Réponses: 3
    Dernier message: 12/04/2006, 09h17

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