使用subprocess.call调用应用程序并添加参数

38

我是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个回答

66

你没有正确地使用call方法。请查看介绍文档或者文档中的任何示例。在call方法中,第一个参数是"args",是一个参数序列,其中arg[0]指定要运行的程序。

因此,当你这样做时:

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

有两种方式subprocess可能会解释这个命令。它应该运行一个名为"g"的程序,并带有参数"p"、"i"、"o"、" "等等。(记住,字符串是字符序列。)或者它可能会运行一个叫做"gpio -g read 17"的程序而没有其他参数。无论哪种方式,它都不会找到这样的程序。(除非你恰好在PATH中有一个名为"g"或"gpio -g read 17"的程序,在这种情况下,它会执行错误的操作而不是给你一个错误...)

你想要的是:

s.call(["gpio", "-g", "read", "17"])
所以,为什么如果你传递shell=True就可以工作呢?因为整个字符串都会传递给 shell,然后 shell ��对命令行进行自己的解析并通过空格分隔。这相当于调用os.system("gpio -g read 17")
请注意,上述所有内容都有点过于简化(它忽略了 Windows,shell 解析也不仅仅是“按空格分隔”,等等),所以你应该实际阅读文档。(另外,撰写subprocess文档的人比我更好些。)

3
使用shell = True参数时,此命令将发送到一个 shell 中,然后由 shell 进行参数分割。 - mgilson
@MarkIngram -- 显然我们同时在评论。 - mgilson
实际上,我看到了这个问题并开始编辑我的答案,然后当我点击“保存”时,你的答案出现了... - abarnert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接