python 系统命令 交互_python中执行命令行的方法 (二)交互式

概述

在上一篇文章(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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值