了解python子流程。检查#u输出';s第一个参数和shell=True
我对如何正确使用Python的子流程模块感到困惑,特别是check_output方法的第一个参数和了解python子流程。检查#u输出';s第一个参数和shell=True,python,linux,shell,subprocess,Python,Linux,Shell,Subprocess,我对如何正确使用Python的子流程模块感到困惑,特别是check_output方法的第一个参数和shell选项。查看下面交互提示的输出。我将第一个参数作为列表传递,并根据是否设置了shell=True,得到不同的输出。有人能解释这是为什么以及输出的输出吗 >>> import subprocess >>> subprocess.check_output(["echo", "Hello World!"]) 'Hello World!\n' >>&g
shell
选项。查看下面交互提示的输出。我将第一个参数作为列表传递,并根据是否设置了shell=True
,得到不同的输出。有人能解释这是为什么以及输出的输出吗
>>> import subprocess
>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!\n'
>>> subprocess.check_output(["echo", "Hello World!"], shell=True)
'\n'
现在,当我将第一个参数作为一个简单的字符串而不是列表传递时,我得到了这个讨厌的堆栈跟踪。为什么会这样?这里发生了什么
>>> 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
的列表中,然后作为一个简单的字符串使用shell=True
时,它就可以工作了。我不理解shell=True
的作用,以及作为列表和字符串传递第一个参数之间的区别。来自以下文档:
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。您只需在上指定shell=True
Windows是指将要执行的命令内置到
shell(例如dir
或copy
)。运行批处理不需要shell=True
基于文件或控制台的可执行文件
在您的情况下,由于echo
在使用shell=True
启动时是一个内置的shell,因此如果要将参数传递给echo
命令,您必须将该命令作为字符串写入,或者传递一个将整个命令作为字符串作为第一个元素的序列。序列的其他元素作为参数传递给shell,而不是您正在调用的命令
在某些操作系统中,echo也是一个程序(通常是/bin/echo
)。这解释了为什么第一个示例没有引发异常,而是输出了'\n'
,而不是预期的'Hello,World\n'
:执行/bin/echo
命令时没有参数,因为该参数已被shell“使用”
调用时引发的错误:
subprocess.check_output("echo Hello World!")
这是因为,由于您没有使用
shell=True
,python正在尝试执行程序echo Hello World代码>即名称为echoHelloWorld的程序代码>。它是一个有效的程序名,但没有具有该名称的程序,因此出现异常。无论何时使用shell=True
,您都会在check\u output
的第一个参数中输入一个引号中的字符串,该字符串表示您通常在shell中输入的内容。“在shell=True的Unix上,shell默认为/bin/sh
”这提供了所有shell功能。“这意味着字符串的格式必须与在shell提示符下键入时的格式完全相同。”这似乎是API设计的缺陷shell
beingTrue/False
不够突出,不足以证明第一个参数(命令)的含义发生如此剧烈(但无声)的变化。顺便说一句,new使用了两个不同的函数:subprocess\u exec
和subprocess\u shell
来相应地运行子流程和shell命令。@J.F.Sebastian他们可能应该添加一个shell\u args
参数,而不是重复使用args
。是的,len(args)>1且shell=True
在大多数情况下都是错误的。
subprocess.check_output("echo Hello World!")