2010-03-08 5 views
7

J'ai un problème avec subprocess.Popen lorsque le paramètre args est donné en tant que séquence.Pourquoi subprocess.Popen ne fonctionne pas quand args est une séquence?

Par exemple:

import subprocess 
maildir = "/home/support/Maildir" 

Cela fonctionne (il imprime la taille correcte de/home/support/Maildir dir):

size = subprocess.Popen(["du -s -b " + maildir], shell=True, 
         stdout=subprocess.PIPE).communicate()[0].split()[0] 
print size 

Mais, cela ne fonctionne pas (essayer) :

size = subprocess.Popen(["du", "-s -b", maildir], shell=True, 
         stdout=subprocess.PIPE).communicate()[0].split()[0] 
print size 

Qu'est-ce qui ne va pas?

+0

Voir aussi: http://stackoverflow.com/questions/1818774/python-subprocess/1818902#1818902 – codeape

+1

« ne fonctionne pas » est pas une description d'erreur utile! – hop

+1

@hop: votre commentaire ne dit pas pourquoi ce n'était pas utile. @pero: Vous pouvez améliorer la question en incluant la sortie que vous obtenez lorsque vous exécutez les commandes. L'affichage des résultats attendus et des résultats obtenus nous permet de savoir si nous voyons ce que vous avez vu lorsque nous essayons de reproduire votre problème. (Bien sûr, puisque vous avez une réponse, il doit y avoir assez d'informations dans la question.) – Mnebuerquo

Répondre

11

De l'documentation

Sur Unix, avec shell = True: [...] Si args est une séquence, le premier élément spécifie la chaîne de commande et éléments supplémentaires seront traités comme des arguments supplémentaires à le shell lui-même. C'est-à-dire Popen fait l'équivalent de:

Popen(['/bin/sh', '-c', args[0], args[1], ...]) 

ce qui se traduit dans votre cas:

Popen(['/bin/sh', '-c', 'du', '-s', '-b', maildir]) 

Cela signifie que -s, -b et maildir sont interprétés comme des options par le shell, pas par du (essayez-le sur la ligne de commande du shell!).

Depuis shell=True n'est pas nécessaire dans votre cas de toute façon, vous pouvez simplement supprimer:

size = subprocess.Popen(['du', '-s', '-b', maildir], 
        stdout=subprocess.PIPE).communicate()[0].split()[0] 

Sinon, vous pouvez simplement utiliser votre approche Orignal, mais vous n'avez pas besoin d'une liste dans ce cas.Vous devez aussi prendre soin des espaces dans le nom du répertoire:

size = subprocess.Popen('du -s -b "%s"' % maildir, shell=True, 
        stdout=subprocess.PIPE).communicate()[0].split()[0] 
1

il devrait être ["du", "-s", "-b", maildir]

5

De document,

Sur Unix, avec shell = True: Si args est une chaîne , il spécifie la chaîne commande pour exécuter à travers le coquille. Si les arguments sont une séquence , le premier élément spécifie la chaîne de commande et tout élément supplémentaire sera traité comme arguments shell supplémentaires.

, essayez

subprocess.Popen("du -s -b " + maildir, ... 

ou

subprocess.Popen(["du","-s","-b",maildir], ... 
+1

Merci. La séquence ["du", "-s", "-b", maildir] fonctionne si je supprime shell = True, ce qui n'est pas nécessaire de toute façon. – mvladic

+0

le point pertinent est que les éléments supplémentaires sont traités comme des arguments _shell_, pas des arguments à – hop

Questions connexes