【问题标题】:Using subprocess.Popen to run a batch file in Windows使用 subprocess.Popen 在 Windows 中运行批处理文件
【发布时间】:2018-07-02 05:57:46
【问题描述】:

为什么我们不能使用Popen 来运行批处理文件?

>>> p = Popen(["filename"], shell=True, stdout = PIPE) 

这很好用,但根据文档,我们不应该使用 shell = True 来“运行批处理文件或基于控制台的可执行文件”。

为什么我们不能在运行批处理文件时使用shell = True?为什么只能用于在cmd中构建?

【问题讨论】:

  • 我不明白为什么使用python代码运行bat文件会复制它
  • 仅供参考,shell=True 不应与 args 列表一起使用。传递命令行字符串。在这种情况下传递列表在 Unix 中是完全错误的,但在 Windows 中也是有问题的。 args 列表始终通过subprocess.list2cmdline 转换为 Windows 中的命令行。问题是它为 C/C++ 程序或调用CommandLineToArgvW 的程序构建了一个命令行。 CMD shell 使用不同的语法。
  • 文档中包含“基于控制台的可执行文件”的意思是,运行控制台应用程序不需要 shell。我认为这是为了消除一些新手程序员的困惑。他们错误地认为 CMD shell 实际上是控制台,但 CMD 只是另一个使用控制台的“基于控制台的可执行文件”。如果控制台应用程序不继承控制台,kernelbase.dll 中的启动代码只会分配一个新控制台。其细节是 Windows 版本之间不同的实现细节。
  • 文档中包含“运行批处理文件”的意思是,如果文件扩展名为 .BAT 或 .CMD,则底层 CreateProcess 会重写命令行以自动使用 shell。所以你不需要shell=True 来运行批处理脚本。然而,需要采取相同的安全预防措施,因为最终该命令是通过cmd /c 运行的。
  • 谢谢现在我明白了谢谢@eryksun提供的信息

标签: python windows python-3.x subprocess


【解决方案1】:

在生产环境中调用subprocess.Popen() 并将shell 参数设置为True 通常是个坏主意。危险之一包括shell injection 漏洞,正如 Python 3 文档所引用的那样:

17.5.2。安全注意事项

与其他一些 popen 函数不同,这个实现永远不会隐式调用 一个系统外壳。这个 意味着所有字符,包括 shell 元字符,都可以安全地 传递给子进程。如果显式调用 shell,通过 shell=True,应用程序有责任确保所有 空格和元字符被适当引用以避免shell 注入漏洞。

来源:https://docs.python.org/3.6/library/subprocess.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 2011-10-13
    • 2015-01-07
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多