python执行外部程序模块pyshell
写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的更多相关文章
- python执行外部命令并获取输出
使用subprocess库 import subprocess out_bytes = subprocess.check_output(['netstat','-a']) out_bytes = su ...
- python 利用python的subprocess模块执行外部命令,获取返回值
有时执行dos命令需要保存返回值 需要导入库subprocess import subprocess p = subprocess.Popen('ping www.baidu.com', shell= ...
- Python入门笔记(26):Python执行环境
一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输入的命令 通过网络来调用命令 执行命令来创建需要处理的输出 动态生成Python语句 导入Pytho ...
- Python调用外部系统命令
利用Python调用外部系统命令的方法可以提高编码效率.调用外部系统命令完成后可以通过获取命令执行返回结果码.执行的输出结果进行进一步的处理.本文主要描述Python常见的调用外部系统命令的方法,包括 ...
- Python学习(25):Python执行环境
转自 http://www.cnblogs.com/BeginMan/p/3191856.html 一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...
- 利用Python读取外部数据文件
不论是数据分析,数据可视化,还是数据挖掘,一切的一切全都是以数据作为最基础的元素.利用Python进行数据分析,同样最重要的一步就是如何将数据导入到Python中,然后才可以实现后面的数据分析.数 ...
- python 执行环境
一些函数 执行其它非python程序 1 一些函数 callable callable()是一个布尔函数,确定一个对象是否可以通过函数操作符(())来调用.如果函数可调用便返回True,否则便是Fal ...
- Python执行系统命令的四种方法
一.os.system方法 在子终端运行系统命令,可以获取命令执行后的返回信息以及执行返回的状态.执行后返回两行结果,第一行是结果, 第二行是执行状态信息,如果命令成功执行,这条语句返回0,否则返回1 ...
- python执行环境
转自 http://www.cnblogs.com/BeginMan/p/3191856.html 一.python特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...
随机推荐
- 关于《Cocos2d-x建工程时避免copy文件夹和库》的更新
在前几篇博文中大概了解了Cocos2d-x引擎的基本结构后打算开始实际操作,便在网上转载了一篇关于VS新建Cocos2d-x项目的文章.今天实际操作的时候发现博主使用的引擎版本和我的不一致(<C ...
- regular expression 基本语法
正则检测网址: http://regexpal.isbadguy.com/ (不包含界定符) 或 http://tool.chinaz.com/regex unicode转换工具 : htt ...
- Redis 入门之编译安装
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主 ...
- google浏览器翻译失败解决方案
用记事本打开 C:\Windows\System32\drivers\etc下hosts文件 在文件末尾加入如下两行 203.208.46.145 translate.google.com 203.2 ...
- [Errno 11004] getaddrinfo failed
该程序是在用python发送邮件的时候出现的 出现这个错误的时候,证明连不上你的帐号,或者登录不上服务器~超时连接 检查下自己的帐号或者服务器的编写有没有正确
- Java--static interface
http://stackoverflow.com/questions/8374646/what-is-a-static-interface-in-java http://stackoverflow.c ...
- 认识元数据和IL(中)<第四篇>
书接上回[第二十四回:认识元数据和IL(上)],我们对PE文件.程序集.托管模块,这些概念与元数据.IL的关系进行了必要的铺垫,同时顺便熟悉了以ILDASM工具进行反编译的基本方法认知,下面是时候来了 ...
- hdu 3874 Necklace(bit树+事先对查询区间右端点排序)
Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful v ...
- linux多线程socket编程一些心得
http://hi.baidu.com/netpet/blog/item/2cc79216d9012b54f2de32b9.html 前段时间将新的web模型办到linux上来,用epoll代替了IO ...
- sendto() 向广播地址发包返回errno 13, Permission denied错误
http://blog.csdn.net/guanghua2_0beta/article/details/52483916 sendto() 向广播地址发包返回errno 13, Permission ...