8 votes

Pourquoi subprocess.Popen ne fonctionne pas lorsque args est une séquence ?

J'ai un problème avec subprocess.Popen lorsque le paramètre args est donné comme une séquence.

Par exemple :

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

Cela fonctionne (il imprime la taille correcte du répertoire /home/support/Maildir) :

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

Mais, cela ne fonctionne pas (essayez-le) :

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

Qu'est-ce qu'il y a ?

12voto

hop Points 15423

De la documentation

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

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

Ce qui se traduit dans votre cas par :

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

Cela signifie que -s , -b y maildir sont interprétés comme des options par le shell, et non 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 le supprimer :

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

Vous pouvez également utiliser votre approche initiale, mais vous n'avez pas besoin de liste dans ce cas. Vous devriez également prendre en compte les espaces dans le nom du répertoire :

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

5voto

YOU Points 44812

En document ,

Sous Unix, avec shell=True : Si args est un chaîne de caractères il spécifie la commande à exécuter par l'intermédiaire du shell. Si args est un séquence le premier élément spécifie la chaîne de commande, et tout éléments supplémentaires seront traités comme des arguments supplémentaires de l'interpréteur de commandes.

Alors, essayez

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

o

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

1voto

SilentGhost Points 79627

Il devrait l'être ["du", "-s", "-b", maildir]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X