Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.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 为什么shell=True与shell=False做相同的事情?_Python_Shell_Subprocess - Fatal编程技术网

Python 为什么shell=True与shell=False做相同的事情?

Python 为什么shell=True与shell=False做相同的事情?,python,shell,subprocess,Python,Shell,Subprocess,因此,我是编程新手(在Linux上学习Python)&我对它了解不多,但我认为有时尝试一些与讲师所说/所做不同的东西是很好的。但不幸的是,我期望发生的事情没有发生 因此,讲师让我键入以下内容: subprocess.call(“ifconfig”,shell=True)。 每当我运行此命令时,它都会给我eth0等。。。 因此,我想知道如果将变量“shell”设置为“False”,会发生什么情况,因此我尝试了以下方法: subprocess.call(“ifconfig”,shell=False)

因此,我是编程新手(在Linux上学习Python)&我对它了解不多,但我认为有时尝试一些与讲师所说/所做不同的东西是很好的。但不幸的是,我期望发生的事情没有发生

因此,讲师让我键入以下内容:
subprocess.call(“ifconfig”,shell=True)
。 每当我运行此命令时,它都会给我eth0等。。。 因此,我想知道如果将变量“shell”设置为“False”,会发生什么情况,因此我尝试了以下方法:
subprocess.call(“ifconfig”,shell=False)

它仍在运行,无论何时运行程序,即使我将变量更改为“False”,它仍将执行命令“ifconfig”


为什么它会一直执行此命令?

如果shell为True,则指定的命令将通过shell执行。如果您使用Python主要是为了在大多数系统shell上提供增强的控制流,并且仍然希望方便地访问其他shell功能,例如shell管道、文件名通配符、环境变量扩展以及~到用户主目录的扩展,那么这将非常有用。但是,请注意,Python本身提供了许多类似于shell的特性的实现(特别是glob、fnmatch、os.walk()、os.path.expandvars()、os.path.expanduser()和shutil)

咨询:


第17.1.1.1节。常用参数

shell=True和shell=False之间的一个区别是将两个参数传递给subprocess.call函数。 例如:

subprocess.call("ls -l", shell=False)
# raises OSError
subprocess.call("ls -l", shell=True)
# returns the directories and files in long format
引用链接

所有调用都需要args,args应该是字符串或程序参数序列。通常首选提供一系列参数,因为它允许模块处理任何必需的参数转义和引用(例如,允许文件名中有空格)。如果传递单个字符串,则shell必须为True(见下文),否则该字符串必须仅命名要执行的程序,而不指定任何参数


shell
参数的描述在文档中,即使如此,它也假定了一些知识,以便知道它的确切功能

简短的版本是,它是一个模式标志,在
shell=True
模式中,它希望参数是单个字符串,如下所示:

#我使用subprocess.run而不是subprocess.call,它们在
#除了subprocess.run之外,它们还具有更好的接口
从子流程导入运行
>>>运行('ls-l',shell=True)
总数0
-rw-r--r--1根根目录0 Aug 26 16:36文件_a.txt
-rw-r--r--1根根目录0 Aug 26 16:36文件_b.txt
CompletedProcess(args='ls-l',返回代码=0)
shell=False
模式下,它希望命令是一个字符串列表,它将在内部转换为一个正确的调用。这通常更可取,因为正确解析shell命令可能会非常棘手:

#这是等效的shell=False命令
>>>运行(['ls','-l'],shell=False)
总数0
-rw-r--r--1根根目录0 Aug 26 16:36文件_a.txt
-rw-r--r--1根根目录0 Aug 26 16:36文件_b.txt
CompletedProcess(args=['ls','-l'],returncode=0)
在标准库中,有一个完整的模块专门用于shell词法分析,名为,通过使用
shell=False
模式,您将永远不会弄乱它,这很好


到目前为止,您的示例是一种特殊情况,因为命令只包含一个参数,在这种情况下,两种模式都只是稍微宽松一点,并假装它们可以处理任何形式的输入—单个字符串或字符串列表

但只要你有两个论点,他们的行为就会不同:

带有参数列表的shell=True,只运行“ls”部分,而不是“ls-l” >>>运行(['ls','-l'],shell=True) 文件a.txt文件b.txt CompletedProcess(args=['ls','-l'],returncode=0) #shell=False,有两个参数作为非列表,情况更糟 >>>运行('ls-l',shell=False) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/usr/lib/python3.6/subprocess.py”,第423行,正在运行 使用Popen(*popenargs,**kwargs)作为流程: 文件“/usr/lib/python3.6/subprocess.py”,第729行,在__ 恢复信号,启动新会话) 文件“/usr/lib/python3.6/subprocess.py”,第1364行,在执行子进程中 引发子项异常类型(错误号、错误消息、错误文件名) FileNotFoundError:[Errno 2]没有这样的文件或目录:“ls-l”:“ls-l”
为什么不呢?请阅读@ForceBru您链接的文档部分只列出了
shell
参数,它没有说明它的功能。@Arne,我找不到直接链接到“常用参数”部分的方法,所以我提供了一个到
调用
函数的链接。尽管如此,我们还是应该仔细阅读模块本身的文档,但是老实说,
子流程
文档非常混乱。如果不是这样,我们就不会有那么多关于it的问题,原则上只要阅读它们就可以解决。但是为什么在我使用
subprocess.call(“ifconfig”,shell=False)
时没有任何变化呢?您希望改变什么
ifconfig
是一个二进制可执行文件。它可以通过shell运行,也可以不通过shell运行,但由于它不使用shell的任何功能,所以在这里没有任何区别。如果您在这里调用
ifconfig*
,如果
shell=True
*
将被shell扩展,因为
shell=False
它将把
*
作为命令行arg传递给
ifconfig
。谢谢!我不知道它没有使用外壳的任何功能!