我的问题更具理论性而非实际性,我找到了更多解答如何而非为什么应该在{{1}中使用列表的答案打电话。
例如众所周知:
Python 2.7.10 (default, Oct 14 2015, 16:09:02)
[GCC 5.2.1 20151010] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> cmd = subprocess.Popen(["python", "-V"], stdout=subprocess.PIPE)
Python 2.7.10
然后我在UNIX中乱搞并找到了一些有趣的东西:
mvarge@ubuntu:~$ strace -f python -V 2>&1
execve("/usr/bin/python", ["python", "-V"], [/* 29 vars */]) = 0
execve
和subprocess
使用的列表模型可能都是相关的,但任何人都可以对此做出很好的解释吗?
提前致谢。
答案 0 :(得分:3)
底层C级表示是*char []
数组。将其表示为Python中的列表只是一种非常自然且透明的映射。
您可以使用字符串而不是shell=True
的列表;然后shell负责将命令行解析为* char []
数组。然而,外壳增加了许多讨厌的复杂性;有关详细说明,请参阅why you want to avoid shell=True
的许多问题。
command line arguments argv
and the environment envp
只是许多操作系统级结构中的两个,它们本质上是一个以空字符结尾的字符串数组。
答案 1 :(得分:3)
进程是操作系统级别的抽象 - 要创建进程,您必须使用OS API来指示您应该使用的内容。 没有必要使用列表,例如,字符串(lpCommandLine
)是本机接口on Windows (CreateProcess()
)。 POSIX uses execv()因此本机接口是一系列参数(argv
)。当然,subprocess
Python模块使用这些接口来运行外部命令(创建新进程)。
技术(无趣)的答案是,在“为什么我们必须”中,“必须”部分不正确,如Windows所示。
要了解“为什么 ”,您可以询问CreateProcess()
,execv()
函数的创建者。
要理解“为什么我们应”使用列表,请查看Unix(列表)和Windows(字符串)的目录:How Command Line Parameters Are Parsed - 应该简单的任务在Windows上很复杂。
主要区别在于POSIX上的调用者负责将命令行拆分为单独的参数。在Windows上时,命令本身会解析其参数。不同的程序可能并且确实使用不同的算法来解析参数。 subprocess
module uses MS C runtime rules (subprocess.list2cmdline()
), to combine args
list into the command line。程序员很难理解如何在Windows上解析参数。