了解python subprocess.check_output的第一个参数和shell = True

我很困惑如何正确使用Python的subprocess模块,特别是check_output方法的第一个参数和shell选项。 检查下面的交互式提示输出。 我将第一个参数作为列表传递,并根据是否设置了shell=True ,获得不同的输出。 有人可以解释为什么这是输出的输出?

 >>> import subprocess >>> subprocess.check_output(["echo", "Hello World!"]) 'Hello World!\n' >>> subprocess.check_output(["echo", "Hello World!"], shell=True) '\n' 

现在,当我把第一个参数作为一个简单的string而不是一个列表,我得到了这个讨厌的堆栈跟踪。 为什么是这样的,这是怎么回事?

 >>> subprocess.check_output("echo Hello World!") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 537, in check_output process = Popen(stdout=PIPE, *popenargs, **kwargs) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__ errread, errwrite) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1228, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory 

但是,当我打开shell = True时,它完美地工作:

 >>> subprocess.check_output("echo Hello World!", shell=True) 'Hello World!\n' 

所以我有点困惑,当第一个参数在列表中WITHOUT shell=True ,然后作为一个简单的stringWITH shell=True时,它工作。 我不明白什么shell=True做的和第一个arg作为列表传递给一个string之间的区别。

Solutions Collecting From Web of "了解python subprocess.check_output的第一个参数和shell = True"

Popen的文档:

shell参数(默认为False )指定是否使用shell作为要执行的程序。 如果shell为True ,建议将args作为字符串而不是序列传递。

shell=True Unix上,shell默认为/bin/sh如果args是一个字符串,则该字符串指定要通过shell执行的命令 。 这意味着字符串的格式必须与在shell提示符下键入的格式完全一致。 这包括,例如,带有空格的引号或反斜线文件名。 如果args是一个序列,则第一个项目指定命令字符串,任何其他项目将被视为shell本身的附加参数 。 也就是说, Popen相当于:

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

shell=True Windows上,COMSPEC环境变量指定缺省shell。 你唯一需要在Windows上指定shell=True时候是你希望执行的命令被内置到shell中(例如dir或者copy )。 您不需要shell=True来运行批处理文件或基于控制台的可执行文件。

在你的情况下,因为echoshell=True时内置的shell=True ,所以如果你想传递参数给echo命令,你必须把这个命令写成一个字符串,或者把一个包含整个命令的序列作为一个字符串作为第一要素。 该序列的其他元素作为参数传递给shell ,而不是您正在调用的命令。

一些操作系统中, echo 也是一个程序(通常是/bin/echo )。 这就解释了为什么你的第一个例子没有引发异常,而是输出'\n'而不是预期的'Hello, World!\n'/bin/echo命令是在没有参数的情况下执行的,因为参数被“消耗”贝壳。

调用时出现的错误:

 subprocess.check_output("echo Hello World!") 

是因为你没有使用shell=True ,所以python试图执行程序echo Hello World! 即名称为echo<space>Hello<space>World! 。 这一个有效的程序名称,但你没有这个名字的程序,因此是例外。

任何时候当你使用shell=True ,你首先输入一个字符串作为第一个参数,用引号代表你通常进入shell的内容。 “在shell = True的Unix上,shell默认为/bin/sh 。” 这给你所有的shell功能。 “这意味着字符串的格式必须与在shell提示符下键入的格式完全相同。” 见Popen