web-dev-qa-db-fra.com

Appeler l'application depuis subprocess.call avec des arguments

Je suis un débutant en Python, et j'ai essayé d'appeler une application en ligne de commande, mais cela échoue:

>>> import subprocess as s
>>> s.call("gpio -g read 17")
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python2.6/subprocess.py", line 470, in call
        return Popen(*popenargs, **kwargs).wait()
    File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
        errread, errwrite)
    File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
        raise child_exception
OSError: [Errno 2] No such file or directory

Mais si j'ajoute Shell=True tout commence à fonctionner. Quelqu'un peut-il expliquer pourquoi?

>>> import subprocess as s
>>> s.call("gpio -g read 17", Shell=True)
>>> 0
28
Mark Ingram

Vous n'utilisez pas l'appel correctement. Regardez l'introduction ou l'un des exemples dans la documentation. Le premier argument d'appel est "args", une séquence d'arguments, où arg [0] est le programme à exécuter.

Donc, quand vous faites cela:

s.call("gpio -g read 17")

Le sous-processus peut interpréter cela de deux manières. Il devrait exécuter un programme appelé "g" avec les arguments "p", "i", "o", "", etc. (N'oubliez pas, les chaînes sont des séquences de caractères.) Il pourrait plutôt exécuter un programme appelé "gpio -g read 17 "sans argument supplémentaire. De toute façon, il ne trouvera pas un tel programme. (Sauf si vous avez un programme appelé "g" ou "gpio -g read 17" sur votre PATH, auquel cas il ne fera pas la bonne chose au lieu de vous donner une erreur ...)

Ce que vous voulez c'est:

s.call(["gpio", "-g", "read", "17"])

Alors, pourquoi cela fonctionne-t-il si vous passez Shell=True? Parce que toute cette chaîne est transmise au Shell, qui effectue ensuite sa propre analyse de la ligne de commande et sépare les choses par des espaces. C'est comme appeler os.system("gpio -g read 17").

Veuillez noter que tout ce qui précède est un peu trop simplifié (il ignore Windows et l'analyse syntaxique de Shell n'est pas seulement "séparée par des espaces", etc.), vous devez donc lire la documentation. (De plus, celui qui a écrit les documents subprocess est un meilleur écrivain que moi.)

45
abarnert