python中执行命令行的方法 (二)交互式
2016-06-22 00:00
609 查看
概述
在上一篇文章(http://blog.csdn.net/styshoo/article/details/48755905)中,我们了解了python执行命令行的几种方法。然而,之前介绍的方法中,却无法进行交互式地调用,即命令只能一次执行,执行之后就结束了。如果我们需要交互式地调用,如调用一个命令,在此过程中间断性的输入输出,那么之前的方法就不适合使用了。想要达到这个目的,就必须使用管道了。在python中,有两种使用管道的方法,一种是前文中提到的popen,不过该函数已经在2.6版本中被建议弃用了,取代它的就是马上会提到的第二种方法:subprocess模块。
使用
subprocess模块是python2.4新加入的模块,而加入该模块的目的,正是为了替代上文中提到的那些模块或函数:os.system、os.spawn、os.popen、popen2和commands等。subprocess模块使用管道是通过该模块的Popen类来实现。class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
创建该类时就生成了一个管道,要通过管道交互,可再直接通过该管道的stdout和stdin对象来实现。然而,默认情况下,subprocess只在子进程结束时才会读取一次标准输出。因此,我们需要将标准输出改为非阻塞的模式。这里,我们以在“sh”下执行ls命令来模拟(真实情况下肯定不会这么简单啦)。
import subprocess import fcntl, os import time pipe = subprocess.Popen("sh", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) flags = fcntl.fcntl(pipe.stdout, fcntl.F_GETFL) fcntl.fcntl(pipe.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) pipe.stdin.write("ls \n") pipe.stdin.flush() time.sleep(2) out = pipe.stdout.read() print out
进阶
在上面的代码中,在从输出读数据之前,有一个休眠两秒的操作。之所以这样,是因为这里所有的操作都是针对子进程的,在主线程中并不会等待。如果没有这个休眠操作,那么就会在执行输入的ls操作同时,就直接尝试从输出读取了,这时,很有可能会出现读取异常。试想下,如果向输入写的是“sleep 10; ls”这样的操作,那么就百分百会出现读取异常了。然而,这种休眠操作并不友好,因为直接写入休眠时间,而实际情况中,我们并不能确认休眠的时间长短。有什么办法可以解决么?当然有,就是类UNIX系统的epoll操作。这里我直接写入代码,有兴趣的同学可以参考下reference来了解详细的情况。
import subprocess import fcntl, os import time import select pipe = subprocess.Popen("sh", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) flags = fcntl.fcntl(pipe.stdout, fcntl.F_GETFL) fcntl.fcntl(pipe.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) pipe.stdin.write("sleep 10; ls \n") pipe.stdin.flush() poll = select.epoll() poll.register(pipe.stdout.fileno()) epoll_list = poll.poll() for fd, events in epoll_list: if fd == pipe.stdout.fileno() and select.EPOLLIN & events: out = pipe.stdout.read() print out
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- [Android]在代码里运行另一个程序的方法
- 评价ui设计作品好坏的八个标准(界面/交互设计研究)
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例