关于os.popen你可能不知道的

前言python

使用python执行一些命令或调用第三方工具是比较常见的状况,实现的方法也不少,如os.system()os.popen()subprocess模块中的函数等等,本文主要介绍一下os.popen(),可能隐藏着你未曾接触的知识点,同时会结合实例进行说明,便于理解。web

 

语法格式sql

首先咱们看下os.popen的语法格式,以下:数据库

os.popen(cmd, mode='r', buffering=-1)微信

 

参数说明:ide

Command --- 调用的命令;函数

mode --- 模式权限能够是 'r'(默认) 'w'工具

bufsize -- 指明了文件须要的缓冲大小:0意味着无缓冲;1意味着行缓冲;其它正值表示使用参数大小的缓冲(大概值,以字节为单位);负的bufsize意味着使用系统的默认值。学习

 

官方释义:spa

Open a pipe to or from command cmd. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is 'r' (default) or 'w'.

从命令cmd打开一个管道,返回值是链接管道的文件对象,经过该对象能够进行读或写。

 

知识点梳理

 

1.  返回值是文件对象

注意:返回值是文件对象既然是文件对象,使用完就应该关闭,对吧?!不信网上搜一下,一大把文章提到这个os.popen都是忘记关闭文件对象的。 因此,推荐的写法是:

  with os.popen(command, "r") as p:
    r = p.read()


     至于with的用法就很少讲了,使用它,不须要显式的写p.close()

 

2.  非阻塞

通俗的讲,非阻塞就是os.popen不会等cmd命令执行完毕就继续下面的代码了,不信?!看下面代码实例:

1.png

从上面实例可知,os.popen执行打开Uedit32.exe这个工具,但从实际执行结果看,Uedit32.exe还没打开,就直接进入了下一条语句,打印了“hello 小蟒社区”。在某些应用场景,可能这并非你指望的行为,那如何让命令执行完后,再执行下一句呢?

处理方法是使用read()readlines()对命令的执行结果进行读操做。

 

3.  彻底阻塞

上面写了该函数是非阻塞的,如今怎么又变成彻底阻塞的呢?感受一头雾水了吧。本质上os.popen是非阻塞的,为了实现阻塞的效果,咱们使用read()readlines()对命令结果进行读,由此产生了阻塞的效果。可是,若是你的命令执行没法退出或进入交互模式,这种“读”将造成彻底阻塞的状况,表现的像程序卡住了。

看下面代码实例1

2.png

os.popen执行了ping  127.0.0.1  -t 该命令会一直执行,除非CTRL+C强制退出,于是,执行readlines读取命令输出时会形成卡住。

 

代码实例2

使用os.popen执行sqlplus命令对数据库进行操做的场景,若是sqlplus执行失败,会进入交互模式,如图所示,此时使用readlines()读取执行结果时也会卡死,效果如上图:

3.png

 

总结

os.popen()在大多数场景都是挺好用方便的,可是也有坑!! 具体应用中,须要注意下。

建议:

1.       在须要读取命令执行结果时,避免在命令没法退出或进入交互模式的场景应用os.popen;

2.       os.popen()没法知足需求时,能够考虑subprocess.Popen();


其余资源

关于python学习、分享、交流,笔者开通了微信公众号【小蟒社区】,感兴趣的朋友能够关注下,欢迎加入,创建属于咱们本身的小圈子,一块儿学python