python - 我什么时候应该使用 subprocess.Popen 而不是 os.popen?

标签 python subprocess popen

似乎既执行子进程又创建管道进行输入/输出,只是 subprocess 较新。

我的问题是,有没有subprocess.Popen可以做而os.popen不能做的功能,所以我们需要新模块subprocess?

为什么Python语言没有选择增强os.popen而是创建了一个新的模块?

最佳答案

简答:永远不要使用os.popen,总是使用subprocess !

正如您从 Python 2.7 中看到的那样 os.popen docs :

Deprecated since version 2.6: This function is obsolete. Use the subprocess module. Check especially the Replacing Older Functions with the subprocess Module section.

旧的 os.popen 系列函数存在各种限制和问题。正如文档所述,2.6 之前的版本在 Windows 上什至不可靠。

subprocess 背后的动机在 PEP 324 -- subprocess - New process module 中有解释。 :

Motivation

Starting new processes is a common task in any programming language, and very common in a high-level language like Python. Good support for this task is needed, because:

  • Inappropriate functions for starting processes could mean a security risk: If the program is started through the shell, and the arguments contain shell meta characters, the result can be disastrous. [1]

  • It makes Python an even better replacement language for over-complicated shell scripts.

Currently, Python has a large number of different functions for process creation. This makes it hard for developers to choose.

The subprocess module provides the following enhancements over previous functions:

  • One "unified" module provides all functionality from previous functions.

  • Cross-process exceptions: Exceptions happening in the child before the new process has started to execute are re-raised in the parent. This means that it's easy to handle exec() failures, for example. With popen2, for example, it's impossible to detect if the execution failed.

  • A hook for executing custom code between fork and exec. This can be used for, for example, changing uid.

  • No implicit call of /bin/sh. This means that there is no need for escaping dangerous shell meta characters.

  • All combinations of file descriptor redirection is possible. For example, the "python-dialog" [2] needs to spawn a process and redirect stderr, but not stdout. This is not possible with current functions, without using temporary files.

  • With the subprocess module, it's possible to control if all open file descriptors should be closed before the new program is executed.

  • Support for connecting several subprocesses (shell "pipe").

  • Universal newline support.

  • A communicate() method, which makes it easy to send stdin data and read stdout and stderr data, without risking deadlocks. Most people are aware of the flow control issues involved with child process communication, but not all have the patience or skills to write a fully correct and deadlock-free select loop. This means that many Python applications contain race conditions. A communicate() method in the standard library solves this problem.

有关基本原理和更多详细信息,请参阅 PEP 链接。

除了安全性和可靠性问题,恕我直言,旧的 os.popen 系列既麻烦又令人困惑。在编写代码时,如果不仔细引用文档,几乎不可能正确使用。相比之下,subprocess 是天赐之物,尽管在使用它时引用文档仍然是明智的。 ;)

有时,人们会建议在 Python 2.7 中使用 os.popen 而不是 subprocess.Popen,例如 Python subprocess vs os.popen overhead因为它更快。当然,它更快,但那是因为它没有做各种对保证其安全工作至关重要的事情!


FWIW,os.popen itself still exists in Python 3 ,但是它是通过 subprocess.Popen 安全实现的,因此您不妨自己直接使用 subprocess.Popenos.popen 系列的其他成员不再存在于 Python 3 中。os.spawn 系列函数仍然存在于 Python 3 中,但文档建议更多可以改用 subprocess 模块提供的强大功能。

关于python - 我什么时候应该使用 subprocess.Popen 而不是 os.popen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41676591/

相关文章:

python - 如何从 Python 中的管道命令获取交互式输出?

python - PyTorch : How to apply the same random transformation to multiple image?

Python模板,有没有办法继承多个html文件?

python - 使用 Deque.popleft 作为函数的参数

python - 如何在 pandas 的 DataFrame.plot.hist 中使用不同的轴刻度?

Python 子进程 : how to pipe to gnuplot a command to plot a variable?

python 导入模块 vs 将脚本作为 subprocess.popen 运行

python - 如何在Python 2.7中将BZ2直接解压到Popen stdin中?

python - 在流程开始执行后(在完成之前)向 subprocess.Popen() 提供标准输入

c - 在 C 代码中将管道写入电子邮件