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特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...
随机推荐
- css制作最简单导航栏
css制作最简单导航栏
- HDU 4939 Stupid Tower Defense
dp:枚举red,dp前i 个塔中有j 个蓝塔的最大伤害. 机智的地方:dp前i 个塔的时候可以同时处理n-i 个红塔,这样就少了个循环...(枚举红塔的循环) #include <iostre ...
- google浏览器翻译失败解决方案
用记事本打开 C:\Windows\System32\drivers\etc下hosts文件 在文件末尾加入如下两行 203.208.46.145 translate.google.com 203.2 ...
- jQuery中的选择器《思维导图》
学习jQuery的课程中,我对jQuery中的选择器有了更深的认识,它的简洁写法,完美的兼容性,可靠的处理机制,都让我们省了很多事, 下面是我在学习过程中对jQuery选择器写的思维导图(全屏查看:& ...
- Lisp之根源
原文:http://www.paulgraham.com/rootsoflisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文,他在这篇论文中对编程的贡献有如 欧几里德对几何的贡献.1 他向我 ...
- scheme I/0 输入输出操作
2.1. open-input-file, read-char, and eof-object? The function (open-input-file filename) is availabl ...
- [置顶] SPL讲解(6)--Condition篇
SmartPersistenceLayer 2.0 之 Condition篇 原理 强大的Condition功能是SPL的一个特性,可以使用Condition完成绝大部分的条件定义,使用 ...
- bzoj2018 [Usaco2009 Nov]农场技艺大赛
Description Input 第1行:10个空格分开的整数: N, a, b, c, d, e, f, g, h, M Output 第1行:满足总重量最轻,且用度之和最大的N头奶牛的总体重模M ...
- ios的一些开源资源
1. http://www.open-open.com/lib/view/open1428646127375.html vim插件:https://github.com/Valloric/YouCom ...
- hdu 4619 Warm up 2 ( 二分图最大匹配 )
题目:Warm up 2 题意:有横竖两种方式放着的多米诺骨牌,相同方向的不可能重叠,但是横放和竖放 的牌可能重叠.移走重叠的牌使剩下的牌最多. 分析:二分图匹配:最大独立集= ...