写python程序的时候需要用到调用外部命令的模块,看了一下,还真不少,头疼,用着不顺手。根据官网推荐,我根据官网的subprocess模块定制了一个自己的shell,同时借鉴了github上面的shellpy模块,而且我觉得go语言的go-sh确实令人喜欢,所以我觉得基于流操作将会改变我们的很多工作。

#!/usr/bin/env python
# -*- coding:utf-8 -*- import shlex
from subprocess import Popen
from subprocess import PIPE def py_ver():
'''
判断python的版本
'''
import sys
return sys.version_info[0] if py_ver() == 2:
builtin_str = str
bytes = str
str = unicode
basestring = basestring
numeric_types = (int, long, float) elif py_ver() == 3:
builtin_str = str
str = str
bytes = bytes
basestring = (str, bytes)
numeric_types = (int, float)
else:
raise ValueError(u'python 版本不正确') def parse_shell_token(t):
import os
# handle '~'
t = os.path.expanduser(t)
# handle env var
t = os.path.expandvars(t)
return t def pipe_to_tmp(data):
'''
把管道或者内存中的数据缓存到临时文件
'''
if isinstance(data, (unicode, str)):
data = data.encode('utf-8') import tempfile
stdin_tmp = tempfile.SpooledTemporaryFile()
stdin_tmp.write(data)
stdin_tmp.seek(0)
return stdin_tmp class Shell(object): def __init__(self, cmd_str, input_pipe=None):
self.cmd_str = cmd_str
self.popen = None
self.input_pipe = input_pipe
self.std = {'out': None, 'err': None} def __getPopen(self):
if self.popen is None:
self.popen = Popen(
map(parse_shell_token, shlex.split(self.cmd_str, posix=False)),
stdin=self.input_pipe, stdout=PIPE, stderr=PIPE)
return self.popen def pipe(self, cmd_str):
input_pipe = None
pp = self.__getPopen()
if pp.stdout.closed:
# 如果命令已经执行,那么就把标准输出的结果保存到临时文件
input_pipe = pipe_to_tmp(self.std['out'])
else:
input_pipe = pp.stdout
# print input_pipe.read()
# pp.stdout.close() # allow pp to receive SIGPIPE?
return Shell(cmd_str, input_pipe=input_pipe) def __communicate(self):
pp = self.__getPopen()
if pp.returncode is None:
self.std['out'], self.std['err'] = pp.communicate() def run(self):
if self.std['out'] is None:
self.__communicate()
print self.std['out'] def stdout(self):
if self.std['out'] is None:
self.__communicate()
return self.std['out'] def stderr(self):
if self.std['err'] is None:
self.__communicate()
return self.std['err'] cmd = Shell
if __name__ == '__main__': # cmd('ls -l').run()
# cmd('ls -l').pipe('grep Shell.py').run()
# cmd('cat').pipe('> hello;cat hello').run() # cmd('ls ~').run()
cmd('echo dddd').run() 下面这个是改良版本,参考了python的bash类库的实现,仅用于学习
 #!/usr/bin/env python
# -*- coding:utf-8 -*-
from subprocess import Popen
from subprocess import PIPE
import shlex def py_ver():
'''
得到python的版本
'''
import sys
return sys.version_info[0]
_ver = py_ver() if _ver == 2:
builtin_str = str
bytes = str
str = unicode
basestring = basestring
numeric_types = (int, long, float) elif _ver == 3:
builtin_str = str
str = str
bytes = bytes
basestring = (str, bytes)
numeric_types = (int, float)
else:
raise ValueError(u'python 版本不正确')
del _ver #解析字符串中的环境变量
def parse_shell_token(t):
import os
#将~等用用户的家目录进行替换
t = os.path.expanduser(t)
#path中可以使用环境变量,'$PATH'...
t = os.path.expandvars(t)
return t class cmd(object):
def __init__(self, *args, **kwargs):
self.stdout = None
self.cmd(*args, **kwargs)
def cmd(self, cmd, env=None, stdout=PIPE):
p = Popen(parse_shell_token(cmd), shell=True,
stdout=stdout, stdin=PIPE, stderr=PIPE, env=env)
self.stdout, self.stderr = p.communicate(input=self.stdout)
self.code = p.returncode
return self
def __repr__(self):
return self.value() def __unicode__(self):
return self.value() def __str__(self):
return self.value() def __nonzero__(self):
return self.__bool__() def __bool__(self):
return bool(self.value()) def value(self):
if not self.stdout:
return ''
return self.stdout.strip() if __name__ == '__main__':
#print cmd('ls -l')
print cmd("ls . | grep 'pyc'")
#print cmd("konsole --hold -e 'konsole --help'")
#print cmd('scrapy list')
print cmd('ls $HOME')
#print cmd('ls ~')

python执行外部程序模块pyshell的更多相关文章

  1. python执行外部命令并获取输出

    使用subprocess库 import subprocess out_bytes = subprocess.check_output(['netstat','-a']) out_bytes = su ...

  2. python 利用python的subprocess模块执行外部命令,获取返回值

    有时执行dos命令需要保存返回值 需要导入库subprocess import subprocess p = subprocess.Popen('ping www.baidu.com', shell= ...

  3. Python入门笔记(26):Python执行环境

    一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输入的命令 通过网络来调用命令 执行命令来创建需要处理的输出 动态生成Python语句 导入Pytho ...

  4. Python调用外部系统命令

    利用Python调用外部系统命令的方法可以提高编码效率.调用外部系统命令完成后可以通过获取命令执行返回结果码.执行的输出结果进行进一步的处理.本文主要描述Python常见的调用外部系统命令的方法,包括 ...

  5. Python学习(25):Python执行环境

    转自 http://www.cnblogs.com/BeginMan/p/3191856.html 一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...

  6. 利用Python读取外部数据文件

      不论是数据分析,数据可视化,还是数据挖掘,一切的一切全都是以数据作为最基础的元素.利用Python进行数据分析,同样最重要的一步就是如何将数据导入到Python中,然后才可以实现后面的数据分析.数 ...

  7. python 执行环境

    一些函数 执行其它非python程序 1 一些函数 callable callable()是一个布尔函数,确定一个对象是否可以通过函数操作符(())来调用.如果函数可调用便返回True,否则便是Fal ...

  8. Python执行系统命令的四种方法

    一.os.system方法 在子终端运行系统命令,可以获取命令执行后的返回信息以及执行返回的状态.执行后返回两行结果,第一行是结果, 第二行是执行状态信息,如果命令成功执行,这条语句返回0,否则返回1 ...

  9. python执行环境

    转自 http://www.cnblogs.com/BeginMan/p/3191856.html 一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...

随机推荐

  1. HDU ACM 题目分类

    模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...

  2. CentOS6.4x64安装mysql5.6.23(rpm)

    #查看已安装的的mysql shell>rpm -qa|grep -i mysql #根据上条命令的结果卸载mysql shell>rpm -e -nodeps mysql* #下载mys ...

  3. [Errno 11004] getaddrinfo failed

    该程序是在用python发送邮件的时候出现的 出现这个错误的时候,证明连不上你的帐号,或者登录不上服务器~超时连接 检查下自己的帐号或者服务器的编写有没有正确

  4. Service、Alarm与BroadcastReceiver的使用方法

    1:定义一个服务类,在服务类中使用AlarmManager 来管理服务的运行 public class WtacService extends Service{ private AlarmManage ...

  5. Qt编程可不可以结合其他的第三方库和本土API?(有zeroMQ的Qt封装,还可轻易使用Python的库)

    作者:渡世白玉链接:http://www.zhihu.com/question/29030777/answer/59378712来源:知乎著作权归作者所有,转载请联系作者获得授权. 可以,十分可以,你 ...

  6. SQL Server索引的维护 - 索引碎片、填充因子 <第三篇>

    实际上,索引的维护主要包括以下两个方面: 页拆分 碎片 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故障排除工具是一样的,因为处理是相同的. 对于非常小的表(比64KB小得多), ...

  7. .net 反编译利器 dnspy

    Binaries Latest release: https://github.com/0xd4d/dnSpy/releases Latest build (possibly unstable): h ...

  8. mongoDB global,startUplog

    1,show logs (Ruiy看到一些人干些事就跟拉shit一样(磨叽),就来气,娃儿的,还不知所谓,抱怨,叫器一大堆!!!,喝喝,就这它还三心二意学一个故事中的主人公小小明上课偷打`皮卡`玩,三 ...

  9. android 分享到新浪微博

    分享到新浪微博,折腾了大半个月,现在终于弄出来了,心里的那个爽呀,太痛快了,哈哈!! 废话少说,首先是认证, 1.进入新浪微博提供的开放平台注册新浪账号. 2.点击’我是开发者‘,创建一个应用,得到C ...

  10. 2、elasticsearch 的安装和插件的安装

    1.安装Elasticsearch集群 1.下载elasticsearch-2.0.0.tar.gz,执行tar -zxvf elasticsearch-2.0.0.tar.gz解压 2.修改conf ...