似乎都执行一个子进程,并创建一个管道进行/输出,只是子进程更新。Python:什么时候应该使用subprocess.Popen而不是os.popen?
我的问题是,subprocess.Popen可以做什么,而os.popen不能,所以我们需要一个新的子进程?
为什么python语言没有选择增强os.popen,但创建了一个新模块?
感谢
似乎都执行一个子进程,并创建一个管道进行/输出,只是子进程更新。Python:什么时候应该使用subprocess.Popen而不是os.popen?
我的问题是,subprocess.Popen可以做什么,而os.popen不能,所以我们需要一个新的子进程?
为什么python语言没有选择增强os.popen,但创建了一个新模块?
感谢
简短的回答:切勿使用os.popen
,总是使用subprocess
!
你可以从Python 2.7 os.popen
docs看到:
自2.6版本不推荐使用:此功能已经过时了。使用
subprocess
模块。特别检查Replacing Older Functions with the subprocess Module部分。
旧功能家族存在各种限制和问题。正如文档中提到的那样,2.6之前的版本在Windows上甚至不可靠。
背后subprocess
的动机是PEP 324 -- subprocess - New process module解释说:
动机
开始新的进程是任何编程语言, 一个共同的任务,并在像Python的高级语言很常见。良好的支持 需要这个任务,因为:
启动过程可能意味着 安全风险不合适的功能:如果程序是通过shell启动,并 参数包含shell元字符,结果可能是 灾难性的。 [1]
它使Python成为 过度复杂的shell脚本的更好替代语言。
目前,Python有 进程创建的大量不同的功能。这使开发人员很难选择。
的子模块提供了以下增强功能比以前 功能:
一个“统一”模块提供了从以前的 功能的全部功能。
跨进程异常:在新进程开始执行之前发生在子进程 中的异常在父进程 中重新提出。这意味着,例如,处理exec() 故障很容易。例如,对于popen2,如果执行失败,则无法检测到 。
用于在fork和exec之间执行自定义代码的钩子。这个 可以用于,例如,改变uid。
没有隐式调用/ bin/sh。这意味着不需要 来逃离危险的shell元字符。
文件描述符重定向的所有组合都是可能的。例如,“python-dialog”[2]需要产生一个进程 并重定向stderr,但不是stdout。目前的功能无法使用临时文件,这是不可能的。
随着子模块,它可以控制,如果之前的新方案是执行 所有打开的 文件描述符应该被关闭。
支持连接多个子进程(shell“管道”)。
通用换行支持。
一个通信()方法,它可以很容易地发送标准输入数据 并读取标准输出和标准错误数据,而没有死锁风险。大多数人都知道 子进程通信中涉及的流量控制问题,但并非所有人都有耐心或 技能来编写完全正确且无死锁的选择循环。这意味着许多Python应用程序包含种族 条件。标准库 中的communications()方法解决了这个问题。
请参阅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.Popen
直接自己。 os.popen
系列的其他成员不再存在于Python 3中.功能家族仍然存在于Python 3中,但文档建议使用由subprocess
模块提供的更强大的功能。
从https://docs.python.org/2/library/os.html#os.popen“自2.6版弃用:此功能已过时,使用'subprocess'模块。” –
请参阅https://www.python。org/dev/peps/pep-0324 /动机与理论部分:防范某些安全风险,跨进程异常,使用文件描述符更好的操作等。 –
除了安全性和可靠性问题,恕我直言,老'os。波潘家族很麻烦,令人困惑。在编写代码时,如果没有密切提及文档,几乎不可能正确使用。相比之下,'subprocess'是天赐之物,尽管在使用文档时参考文档仍然是明智之举。 ;) –