了解python subprocess.check_output的第一个参数和shell = True [英] Understanding python subprocess.check_output's first argument and shell=True
问题描述
我对如何正确使用Python的子进程模块感到困惑,特别是check_output方法的第一个参数和shell
选项.从下面的交互式提示中查看输出.我将第一个参数作为列表传递,并且根据是否设置了shell=True
,我得到了不同的输出.有人可以解释为什么会这样以及输出的结果吗?
I'm confused on how to correctly use Python's subprocess module, specifically, the check_output method's first argument and the shell
option. Check out the output from the interactive prompt below. I pass the first argument as a list and depending on whether shell=True
is set, I get different output. Can someone explain why this is and the output that is outputted?
>>> import subprocess
>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!\n'
>>> subprocess.check_output(["echo", "Hello World!"], shell=True)
'\n'
现在,当我将第一个参数作为简单字符串而不是列表传递时,我得到了此讨厌的堆栈跟踪.为什么会这样,这是怎么回事?
Now when I pass the first argument as a simple string instead of a list, I get this nasty stack trace. Why is that and what's going on here?
>>> 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时,它可以正常工作:
However, when I turn on shell=True, it then works perfectly:
>>> subprocess.check_output("echo Hello World!", shell=True)
'Hello World!\n'
所以我有点困惑,当第一个arg在不带shell=True
的列表中,然后作为带shell=True
的简单字符串时,它可以工作.我不了解shell=True
的作用以及将第一个arg作为列表与字符串传递之间的区别.
So I'm a little confused, it works when the first arg is in a list WITHOUT shell=True
and then works as a simple string WITH shell=True
. I'm not understanding what shell=True
does and the difference between passing the first arg as a list vs a string.
推荐答案
来自 Popen
:
shell参数(默认为
False
)指定是否使用 shell作为要执行的程序.如果shell是True
,则为 建议将args
作为字符串而不是作为序列传递.
The shell argument (which defaults to
False
) specifies whether to use the shell as the program to execute. If shell isTrue
, it is recommended to passargs
as a string rather than as a sequence.
在带有shell=True
的Unix上,shell默认为/bin/sh
. 如果args是一个
字符串,该字符串指定要通过外壳执行的命令.
这意味着该字符串必须完全按照其格式进行格式化
在shell提示符下键入时.例如,这包括引号或
反斜杠转义使用空格的文件名. 如果args是一个
顺序,第一项指定命令字符串,以及任何
其他项目将被视为外壳程序的其他参数
本身.也就是说,Popen
等效于:
On Unix with shell=True
, the shell defaults to /bin/sh
. If args is a
string, the string specifies the command to execute through the shell.
This means that the string must be formatted exactly as it would be
when typed at the shell prompt. This includes, for example, quoting or
backslash escaping filenames with spaces in them. If args is a
sequence, the first item specifies the command string, and any
additional items will be treated as additional arguments to the shell
itself. That is to say, Popen
does the equivalent of:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
在具有shell=True
的Windows上,COMSPEC环境变量指定
默认外壳.唯一需要在以下位置指定shell=True
的时间
Windows是您要执行的命令内置在
外壳程序(例如dir
或copy
).您不需要shell=True
即可运行批处理
文件或基于控制台的可执行文件.
On Windows with shell=True
, the COMSPEC environment variable specifies
the default shell. The only time you need to specify shell=True
on
Windows is when the command you wish to execute is built into the
shell (e.g. dir
or copy
). You do not need shell=True
to run a batch
file or console-based executable.
在您的情况下,由于echo
是与shell=True
一起启动时内置的shell,因此,如果要将参数传递给echo
命令,则必须将命令编写为字符串或传递以 whole 命令作为字符串的第一个元素的序列.序列中的其他元素作为参数传递给shell ,而不是传递给您正在调用的命令.
In your case, since echo
is a shell built-in when launched with shell=True
, if you want to pass arguments to the echo
command you must either write the command as a string or pass a sequence that has the whole command as a string as first element. Other elements of the sequence are passed as arguments to the shell, not to the command you are invoking.
在某些操作系统中,echo
也是 程序(通常为/bin/echo
).这就解释了为什么第一个示例没有引发异常而是输出'\n'
而不是预期的'Hello, World!\n'
的原因:/bin/echo
命令在没有参数的情况下执行,因为该参数已被外壳消耗".
In some OSes echo
is also a program (usually /bin/echo
). This explains why your first example didn't raise an exception but outputs '\n'
instead of the expected 'Hello, World!\n'
: the /bin/echo
command was executed without arguments, because the argument was "consumed" by the shell.
调用时引发错误:
subprocess.check_output("echo Hello World!")
是由于以下事实:由于您没有使用shell=True
,因此python试图执行程序echo Hello World!
,即名称为echo<space>Hello<space>World!
的程序.它是有效的程序名称,但是您没有使用该名称的程序,因此是一个例外.
is due to the fact that, since you did not use shell=True
, python is trying to execute the program echo Hello World!
i.e. a program that has the name echo<space>Hello<space>World!
. It is a valid program name, but you there's no program with that name, hence the exception.
这篇关于了解python subprocess.check_output的第一个参数和shell = True的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!