Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解python子流程。检查#u输出';s第一个参数和shell=True_Python_Linux_Shell_Subprocess - Fatal编程技术网

了解python子流程。检查#u输出';s第一个参数和shell=True

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

我对如何正确使用Python的子流程模块感到困惑,特别是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'
现在,当我将第一个参数作为一个简单的字符串而不是列表传递时,我得到了这个讨厌的堆栈跟踪。为什么会这样?这里发生了什么

>>> 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
being
True/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!")