Python 为什么命令及其参数必须位于subprocess.Popen的列表中?
我试过了Python 为什么命令及其参数必须位于subprocess.Popen的列表中?,python,linux,subprocess,Python,Linux,Subprocess,我试过了 import subprocess p = subprocess.Popen("ls -la /etc", stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.stdout.read().decode() 这让我 FileNotFoundError: [Errno 2] No such file or directory: 'ls -la /etc': 'ls -la /etc' 跟随 是的 import subprocess p
import subprocess
p = subprocess.Popen("ls -la /etc", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdout.read().decode()
这让我
FileNotFoundError: [Errno 2] No such file or directory: 'ls -la /etc': 'ls -la /etc'
跟随 是的
import subprocess
p = subprocess.Popen(["ls", "-la", "/etc"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdout.read().decode()
这确实有效
为什么呢?为什么我必须拆分命令及其参数?这种设计背后的基本原理是什么
Python版本:
3.7.3 (default, Mar 27 2019, 22:11:17)
[GCC 7.3.0]
根据,它取决于shell=
关键字参数关于字符串与列表的工作方式(粗体表示可能导致您的行为的原因):
args应该是一系列程序参数,或者是单个字符串或类似路径的对象。默认情况下,如果args是序列,则要执行的程序是args中的第一项。如果args是字符串,则解释取决于平台,如下所述。有关与默认行为的其他差异,请参见shell和可执行参数。除非另有说明,否则建议按顺序传递args
在POSIX上,如果args是字符串,则该字符串将被解释为要执行的程序的名称或路径。但是,只有在不向程序传递参数的情况下才能执行此操作。
再往下
在shell=True的POSIX上,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
根据,它取决于shell=
关键字参数关于字符串与列表的工作方式(粗体表示可能导致您的行为的原因):
args应该是一系列程序参数,或者是单个字符串或类似路径的对象。默认情况下,如果args是序列,则要执行的程序是args中的第一项。如果args是字符串,则解释取决于平台,如下所述。有关与默认行为的其他差异,请参见shell和可执行参数。除非另有说明,否则建议按顺序传递args
在POSIX上,如果args是字符串,则该字符串将被解释为要执行的程序的名称或路径。但是,只有在不向程序传递参数的情况下才能执行此操作。
再往下
在shell=True的POSIX上,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
这就是UNIX上所有进程调用的工作方式。
在后台,在UNIX上运行程序通常通过以下步骤完成:
subprocess.Popen
公开了数组接口,因为数组接口是操作系统在后台实际执行的操作
当您在shell上运行ls/tmp
时,该shell会将字符串转换为数组,然后自己执行上述步骤——但它提供了更多的控制(并避免了严重的错误——如果有人创建一个名为/tmp/$(rm-rf~)
的文件,您不希望尝试cat/tmp/$(rm-rf~)
来删除主目录)当您自己进行转换时。这就是所有进程调用在UNIX上工作的方式。
在后台,在UNIX上运行程序通常通过以下步骤完成:
subprocess.Popen
公开了数组接口,因为数组接口是操作系统在后台实际执行的操作
在shell上运行ls/tmp
时,该shell将字符串转换为数组并