Вопрос по python, python-2.6, raspberry-pi, process – Вызов приложения из subprocess.call с аргументами

23

Я новичок в Python, и я пытался вызвать приложение командной строки, но это не удалось:

>>> 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

Но тогда, если я добавлюshell=True все начинает работать. Может кто-нибудь объяснить, почему?

>>> import subprocess as s
>>> s.call("gpio -g read 17", shell=True)
>>> 0

Ваш Ответ

1   ответ
42

Вы не используете право вызова. смотреть навступление или любой из примеров в документах. Первым аргументом вызова является «args», последовательность аргументов, где arg [0] - программа для запуска.

Итак, когда вы делаете это:

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

Подпроцесс может интерпретировать это двумя способами. Он должен запустить программу под названием "g" с аргументами "p", "i", "o", " & quot; и т. д. (Помните, что строки - это последовательности символов.) Вместо этого он может запустить программу под названием & quot; gpio -g read 17 & quot; без дополнительных аргументов. В любом случае, она не найдет такой программы. (Если у вас в программе PATH нет программы под названием «g» или «gpio -g read 17»; в этом случае она будет делать не то, что нужно, вместо того, чтобы выдавать ошибку »

То, что вы хотите, это:

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

Итак, почему это работает, если вы передаетеshell=True? Потому что вся эта строка передается в оболочку, которая затем выполняет собственный анализ командной строки и разделяет вещи пробелами. Это как звонитьos.system("gpio -g read 17").

Обратите внимание, что все вышеперечисленное несколько упрощено (оно игнорирует Windows, и разбор оболочки на самом деле не просто "разделяется пробелами" и т. Д.), Поэтому вам следует прочитать документацию. (Кроме того, кто бы ни написалsubprocess Документы лучше, чем я.)

Почему добавление & quot; shell = True & quot; сделай так, чтоб это работало? Mark Ingram
И сshell = Trueэта команда отправляется в оболочку, которая затем выполняет разбиение аргумента разделения.
На самом деле, я увидел вопрос и начал редактировать свой ответ, а затем, когда я нажал «Сохранить» появился ваш ответ & # x2026;
@MarkIngram - очевидно, мы комментировали одновременно.

Похожие вопросы