subprocess.Popen和os.system之间的区别

199

subprocess.Popen()os.system()有什么区别?

5个回答

161
如果您查看Python文档的subprocess部分,您会注意到有一个示例,说明如何将os.system()替换为subprocess.Popen():
sts = os.system("mycmd" + " myarg")

...做的是和...一样的事情...

sts = Popen("mycmd" + " myarg", shell=True).wait()

“改进过的”代码看起来更加复杂,但是它更好,因为一旦你了解了subprocess.Popen(),就不需要任何其他工具了。 subprocess.Popen() 取代了分散在另外三个Python模块中的几个其他工具(os.system()只是其中之一)。
如果有帮助,可以把subprocess.Popen()看作是一个非常灵活的os.system()

1
你也可以使用 sts = p.wait() 替代最后一行。 - Sven Marnach
1
@JacobMarble 假设我正在从另一个Python脚本调用一个Selenium爬虫脚本,哪个选项可以让我在完成爬取脚本之后才执行下一行代码?也就是说,在执行继续之前,我的爬取应该完成。 - praxmon
也许还可以提到 https://dev59.com/lHA75IYBdhLWcg3wqK__,以指出如果可能的话,应该避免使用 shell=True。拥有这个选项是 subprocess.Popen() 及其辅助函数的好处之一。 - tripleee
1
如果您想阻塞流并等待命令完成其工作,请查看:https://dev59.com/Q3E85IYBdhLWcg3wUByz#2837319 @PrakharMohanSrivastava - Amir Hossein Baghernezad
@PrakharMohanSrivastava,一般来说os.systemsubprocess.call/popen/run都会阻塞/等待命令执行完成:https://dev59.com/PmYq5IYBdhLWcg3w8lNo#14059648 - alpha_989
(小事实)如果您在2022年使用相同的文档,则sts = os.system("mycmd" + " myarg")现在变成了retcode = call("mycmd" + " myarg", shell=True) - user13237611

84

subprocess.Popen()os.system() 的严格超集。


13
这是完美而优雅的答案。 - Farshid Ashouri
42
它很优雅,但不完整,因为它没有描述os.system缺少了什么,或者为什么你可能需要使用Popen - naught101
并不足以理解解决方案。可以更详细地举例说明。 - kta

39

os.system相当于Unix system命令,而subprocess是一个帮助模块,旨在提供许多由Popen命令提供的功能,具有更简单和可控的接口。这些命令设计类似于Unix Popen命令。

system()通过调用/bin/sh -c command来执行指定为command的命令,并在命令完成后返回。

然而:

popen()函数通过创建管道、fork和调用shell来打开进程。

如果你想决定使用哪个命令,则绝对使用subprocess,因为你拥有所有执行的设施,同时还可以额外控制进程。


好的,那么在Windows环境下有没有办法同时执行os.system和popen呢?我是新手,需要深入挖掘一下。 - Arovit
是的,在Windows环境下,您可以同时使用os.system和subprocess。请查看effbot.org(Python标准库在线书籍)的基本教程。 - Senthil Kumaran

26

Subprocess 基于 popen2,因此有许多优点 - 这里PEP列出了完整的列表,但其中一些包括:

  • 在 shell 中使用 pipe
  • 更好的换行符支持
  • 更好的异常处理

9
当在Windows上运行Python(CPython)时,<built-in function system> os.system 将在幕后执行 _wsystem,而如果您使用的是非Windows操作系统,则将使用system
相反,Popen应在Windows上使用CreateProcess,在基于posix的操作系统中使用_posixsubprocess.fork_exec
也就是说,来自os.system文档的重要建议是:

子进程模块提供了更强大的生成新进程和检索其结果的功能;使用该模块比使用此函数更可取。请参阅子进程文档中的“用子进程模块替换旧函数”部分,以获取一些有用的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接