关于python:使用参数从subprocess.call调用app

Calling app from subprocess.call with arguments

我是Python的初学者,我一直在尝试调用命令行应用程序,但失败了:

1
2
3
4
5
6
7
8
9
10
11
>>> 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,一切都开始工作了。有人能解释为什么吗?

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

你没有正确使用Call。查看介绍或文档中的任何示例。调用的第一个参数是"args",一系列参数,其中arg[0]是要运行的程序。

所以,当你这样做的时候:

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

子流程有两种解释方法。它应该运行一个名为"g"的程序,参数为"p"、"i"、"o"等(记住,字符串是字符序列)。它可以运行一个名为"gpio-g read 17"的程序,而不需要其他参数。不管怎样,它都找不到这样的程序。(除非您的路径上碰巧有一个名为"g"或"gpio-g read 17"的程序,在这种情况下,它将做错误的事情,而不是给您一个错误…)

你想要的是:

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

那么,如果你通过了shell=True,为什么这会起作用?因为整个字符串被传递给shell,shell随后对命令行进行自己的解析,并用空格分隔事物。就像打电话给os.system("gpio -g read 17")

请注意,以上所有内容都有点过于简单(它忽略了Windows,而shell解析并不仅仅是"用空格分隔"的,等等),因此您应该实际阅读文档。(而且,写《江户记》的人比我写得更好。)