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特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...
随机推荐
- 如何只克隆git仓库中的一个分支?
git clone -b 例如: git clone -b 指定的分支名字
- project euler 16:Power digit sum
>>> sum([int(i) for i in str(2**1000)]) 1366 >>>
- php pdf word excel 操作方法
很早的时候,用php生成execl都是件麻烦的事,我一般都会用csv来替代,现在这类工具就很多了,并且比较成熟了.不光有excel的,word,pdf. 1,php excelreader操作exce ...
- 还是畅通工程(1233 并查集+kruskal)
还是畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- 海量数据处理利器greenplum——初识
简介及适用场景 如果想在数据仓库中快速查询结果,可以使用greenplum. Greenplum数据库也简称GPDB.它拥有丰富的特性: 第一,完善的标准支持:GPDB完全支持ANSI SQL 200 ...
- 管理Activity,随时随地控制Activity的销毁工作
public class ActivityManager { public static List<Activity> activityList = new ArrayList<Ac ...
- Keil C51 中指针的使用
指针是C语言中比较难的一个内容,Keil C51在指针方面有和标准C不一样的地方,今天看了一些资料学习了一下Keil C51 中指针的使用. keil51的指针,包含两种指针:普通指针,兼容标准C:内 ...
- C# DES_AES_MD5_加密_解密
一.DES加解密 DES一共就有4个参数参与运作:明文.密文.密钥.向量.其中这4者的关系可以理解为: 密文=明文+密钥+向量: 明文=密文-密钥-向量: 为什么要向量这个参数呢?因为如果有一篇文章, ...
- 2014.8.4我出的模拟赛【NTR酋长】
NTR酋长 (ntr.pas/.c/.cpp) 黄巨大终于如愿以偿的进入了czy的后宫中……但是czy很生气……他要在黄巨大走到他面前的必经之路上放上几个NTR酋长来阻挡黄巨大. 众所周知,NTR酋长 ...
- bzoj1649 [Usaco2006 Dec]Cow Roller Coaster
Description The cows are building a roller coaster! They want your help to design as fun a roller co ...