子流程中'shell = True'的实际含义?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (10)

我正在使用该subprocess模块调用不同的进程。但是,我有一个问题。

在以下代码中:

callProcess = subprocess.Popen(['ls', '-l'], shell=True)

callProcess = subprocess.Popen(['ls', '-l']) # without shell

两者都有效。阅读完文档后,我才知道这shell=True意味着通过shell执行代码。所以这意味着如果没有,这个过程是直接开始的。

那么,我应该怎样选择我的案例 - 我需要运行一个流程并获得它的输出。我从shell或其外部调用它有什么好处。

提问于
用户回答回答于

不通过shell调用的好处是你没有调用“神秘程序”。在POSIX上,环境变量SHELL控制哪个二进制文件被调用为“shell”。在Windows上,没有Bourne shell后代,只有cmd.exe。

所以调用shell会调用用户选择的程序,并且依赖于平台。一般来说,避免通过shell进行调用。

通过shell调用的确可以让你根据shell的通常机制来扩展环境变量和文件大小。在POSIX系统上,shell将文件扩展到文件列表。在Windows中,一个文件名匹配(例如,“*。*”)不受外壳,反正扩大(但在命令行环境变量由cmd.exe的展开)。

如果你认为你想要环境变量扩展和文件扩展,研究ILS1992年ISH对通过shell执行子程序调用的网络服务的攻击。例子包括sendmail涉及的各种后门ILS

总之,使用shell=False

用户回答回答于

通过shell执行程序意味着传递给程序的所有用户输入都是根据被调用的shell的语法和语义规则来解释的。充其量,这只会给用户带来不便,因为用户必须遵守这些规则。例如,包含特殊外壳字符(如引号或空格)的路径必须转义。最糟糕的是,它会导致安全漏洞,因为用户可以执行任意程序。

shell=True有时可以方便地使用特定的shell特性,如分词或参数扩展。但是,如果需要这样的功能,则可以使用其他模块(例如,os.path.expandvars()用于参数扩展或shlex分词)。这意味着更多的工作,但避免了其他问题。

总之:避免shell=True一切手段。

扫码关注云+社区