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特定的执行环境 在当前脚本继续进行 创建和管理子进程 执行外部命令或程序 执行需要输 ...
随机推荐
- spring中连接池的配置
在默认通过myeclipse生成的配置里,spring使用的是apache的dbcp连接池 <bean id="dataSource" class="org.apa ...
- 基于cygwin构建u-boot(一)环境搭建
从本文开始,更系统的描述基于cygwin构建u-boot. 之前<痛苦的版本对齐>系列,对于cygwin环境下Sourcery CodeBench,u-boot-1.1.6的构建有侧面的说 ...
- python笔记之bisect模块
python笔记之bisect模块 当你决定使用二分搜索时,这个模块会给你带来很大的帮助. 例子 import bisect L = [1,3,3,6,8,12,15] x = 3 #在L中查找x,x ...
- Node.js how to respond to an upgrade request?
You just need to call socket.write with the appropriate HTTP syntax as plain text along these lines ...
- USB Mass Storage学习笔记-STM32+FLASH实现U盘
一.内容概述 采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘. 1.STM32的USB控制器 STM32F103的MCU自带USB从控制器 ...
- Windows7里的“计算器”你真的会用吗?
“计算器”是不同Windows版本中的必备工具,虽然功能单一,但的确是人们日常工作中不可缺少的辅助工具,本文就来谈谈它的使用. 一.标准型和科学型两种面板 我们既可从Windows附件菜单中启动它,也 ...
- Qt中一些常用的格式转换
转自:http://blog.csdn.NET/yh_1988/article/details/7190356 用Qt经常头痛于一些格式不能通用的问题 在此记录备用 1 (20120112)QStri ...
- 《how to design programs》第11章自然数
这章让我明白了原来自然数的定义本来就是个递归的过程. 我们通常用枚举的方式引出自然数的定义:0,1,2,3,等等(etc).最后的等等是什么意思?唯一能把等等从描述自然数的枚举方法中去除的方法是自引用 ...
- c++ ifstream ofstream 文件流
#include <fstream>ofstream //文件写操作 内存写入存储设备 ifstream //文件读操作,存储设备读区到内存中fstream //读写操作,对打开的文件可进 ...
- PHP伪静态与短链接
如今,Web服务高速发展的时代,各式各类的门户网站,如新浪http://www.sina.com.腾讯http://www.qq.com,这些网站大家都很容易记住,因为这种名称都是有规则和含义的.如果 ...