[TOC]
* * * * *
> * 模块的分类
> 1. python内置模块(标准库)
> 2. 开源模块
> 3. 自定义模块
>
## 1. shelve模块
在python3中我们使用json或者pickle持久化数据,能dump多次,但只能load一次,因为先前的数据已经被后面dump的数据覆盖掉了。如果我们想要实现dump和load多次,可以使用shelve模块。shelve模块可以持久化所有pickle所支持的数据类型。类似于键值对的文件序列化
1. 写入数据(打开文件,写入键值,关闭文件)
~~~
import shelve
import datetime
d = shelve.open('shave.txt')
info = {"age":25,"name":'dailin'}
name = ['alex','rain','peter']
d['info'] = info
d['name'] = name
date = datetime.datetime.now()
d['date'] = date
d.close()
~~~
2. 读数据(打开文件,获取键对应的值,关闭文件)
~~~
import shelve
d = shelve.open('shave.txt')
print(d.get('info'))
d.close()
~~~
## 2. os
* 文件与路径的操作
在自动化测试中,经常需要查找操作文件,比如说查找配置文件(从而读取配置文件的信息),查找测试报告(从而发送测试报告邮件),经常要对大量文件和大量路径进行操作,这就依赖于os模块,所以今天整理下比较常用的几个方法。网上这方面资料也很多,每次整理,只是对自己所学的知识进行梳理,从而加深对某个模块的使用。
#### 2.1 当前路径及路径下的文件
* os.getcwd(): 查看当前所在路径。
* os.listdir(path): 列举目录下的所有文件。返回的是列表类型。
~~~
>>> import os
>>> os.getcwd()
'D:\\pythontest\\ostest'
>>> os.listdir(os.getcwd())
['hello.py', 'test.txt']
~~~
#### 2.2 绝对路径
* os.path.abspath(path):返回path的绝对路径。
~~~
# 获取当前绝对路径 .
>>> os.path.abspath('.')
'D:\\pythontest\\ostest'
# 获取当前路径上一级绝对路径 ..
>>> os.path.abspath('..')
'D:\\pythontest'
~~~
#### 2.3 查看路径的文件夹部分和文件名部分
* os.path.split(path):
将路径分解为(文件夹,文件名),返回的是元组类型。可以看出,若路径字符串最后一个字符是\,则只有文件夹部分有值;若路径字符串中均无\,则只有文件名部分有值。若路径字符串有\,且不在最后,则文件夹和文件名均有值。且返回的文件夹的结果不包含\.
* os.path.join(path1,path2,...):将path进行组合,若其中有绝对路径,则之前的path将被删除。
~~~
# 切分路径与文件
>>> os.path.split('D:\\pythontest\\ostest\\Hello.py')
('D:\\pythontest\\ostest', 'Hello.py')
>>> os.path.split('.')
('', '.')
>>> os.path.split('D:\\pythontest\\ostest\\')
('D:\\pythontest\\ostest', '')
>>> os.path.split('D:\\pythontest\\ostest')
('D:\\pythontest', 'ostest')
>>> os.path.join('D:\\pythontest', 'ostest')
'D:\\pythontest\\ostest'
# 路径与文件拼接
>>> os.path.join('D:\\pythontest\\ostest', 'hello.py')
'D:\\pythontest\\ostest\\hello.py'
# 绝对路径与绝对路径拼接,前边的被覆盖
>>> os.path.join('D:\\pythontest\\b', 'D:\\pythontest\\a')
'D:\\pythontest\\a'
~~~
* os.path.dirname(path):返回path中的文件夹部分,结果不包含'\'
~~~
>>> os.path.dirname('D:\\pythontest\\ostest\\hello.py')
'D:\\pythontest\\ostest'
>>> os.path.dirname('.')
''
>>> os.path.dirname('D:\\pythontest\\ostest\\')
'D:\\pythontest\\ostest'
>>> os.path.dirname('D:\\pythontest\\ostest')
'D:\\pythontest'
~~~
* os.path.basename(path):返回path中的文件名。
~~~
>>> os.path.basename('D:\\pythontest\\ostest\\hello.py')
'hello.py'
>>> os.path.basename('.')
'.'
>>> os.path.basename('D:\\pythontest\\ostest\\')
''
>>> os.path.basename('D:\\pythontest\\ostest')
'ostest'
~~~
#### 2.4 查看文件时间
* os.path.getmtime(path):
文件或文件夹的最后修改时间,从新纪元到访问时的秒数。
* os.path.getatime(path):
文件或文件夹的最后访问时间,从新纪元到访问时的秒数。
* os.path.getctime(path):
文件或文件夹的创建时间,从新纪元到访问时的秒数。
~~~
>>> os.path.getmtime('D:\\pythontest\\ostest\\hello.py')
1481695651.857048
>>> os.path.getatime('D:\\pythontest\\ostest\\hello.py')
1481687717.8506615
>>> os.path.getctime('D:\\pythontest\\ostest\\hello.py')
1481687717.8506615
~~~
#### 2.5 查看文件大小
* os.path.getsize(path):
文件或文件夹的大小,若是文件夹返回0。
~~~
>>> os.path.getsize('D:\\pythontest\\ostest\\hello.py')
58L
>>> os.path.getsize('D:\\pythontest\\ostest')
0L
~~~
#### 2.6 查看文件是否存在
* os.path.exists(path):
文件或文件夹是否存在,返回True 或 False。
~~~
>>> os.listdir(os.getcwd())
['hello.py', 'test.txt']
>>> os.path.exists('D:\\pythontest\\ostest\\hello.py')
True
>>> os.path.exists('D:\\pythontest\\ostest\\Hello.py')
True
>>> os.path.exists('D:\\pythontest\\ostest\\Hello1.py')
False
~~~
#### 2.7 一些表现形式参数
os中定义了一组文件、路径在不同操作系统中的表现形式参数,如:
~~~
>>> os.sep # 系统路径分隔符
'\\'
>>> os.extsep
'.'
>>> os.pathsep # 输出用于分割文件路径的字符串
';'
>>> os.linesep # 获取系统换行符
'\r\n'
~~~
#### 2.8 实例说明
在自动化测试过程中,常常需要发送邮件,将最新的测试报告文档发送给相关人员查看,这是就需要查找最新文件的功能。
举例:查找文件夹下最新的文件。
~~~
import os
def new_file(test_dir):
#列举test_dir目录下的所有文件(名),结果以列表形式返回。
lists=os.listdir(test_dir)
#sort按key的关键字进行升序排序,lambda的入参fn为lists列表的元素,获取文件的最后修改时间,所以最终以文件时间从小到大排序
#最后对lists元素,按文件修改时间大小从小到大排序。
lists.sort(key=lambda fn:os.path.getmtime(test_dir+'\\'+fn))
#获取最新文件的绝对路径,列表中最后一个值,文件夹+文件名
file_path=os.path.join(test_dir,lists[-1])
return file_path
#返回D:\pythontest\ostest下面最新的文件
print new_file('D:\\system files\\workspace\\selenium\\email126pro\\email126\\report')
~~~
~~~
# 关于lambda的用法(python中单行的最小函数):
key=lambda fn:os.path.getmtime(test_dir+'\\'+fn)
#相当于
def key(fn):
return os.path.getmtime(test_dir+'\\'+fn)
~~~
#### 2.9 遍历文件
os.walk(top, topdown=True, onerror=None, followlinks=False)
可以得到许多个三元tupple(dirpath, dirnames, filenames), 即每个文件夹的(文件夹,文件夹所有子文件夹列表,文件夹下的所有文件列表)
dirpath 是一个string,代表目录的路径,
dirnames 是一个list,包含了dirpath下所有子目录的名字。
filenames 是一个list,包含了非目录文件的名字。
这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name).
循环遍历work目录下的文件
~~~
for dirpath, dirnames, filenames in os.walk('C:\\Users\\Administrator\\Desktop\\work'):
for file in filenames:
fullpath = os.path.join(dirpath, file)
print(fullpath)
~~~
~~~
# 根目录 # 根目录下的子目录 # 根目录下的文件
('C:\\Users\\Administrator\\Desktop\\work', ['fastdfsClient', 'PythonRedis'], ['daily.txt', 'daily.txt.bak', 'fastdfsClient.rar',
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient', ['.idea', '.settings', 'bin', 'lib', 'src'], ['.classpath', '.project', 'fastdfsClient.iml'])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\.idea', ['libraries'], ['misc.xml', 'modules.xml', 'workspace.xml'])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\.idea\\libraries', [], ['jdk1_8.xml'])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\.settings', [], ['org.eclipse.jdt.core.prefs'])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\bin', ['cn'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\bin\\cn', ['itcast'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\bin\\cn\\itcast', ['fastdfs'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\bin\\cn\\itcast\\fastdfs', ['cliennt'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\bin\\cn\\itcast\\fastdfs\\cliennt', [], ['FastdfsClientTest.class', 'fdfs_client.conf'])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\lib', [], ['fastdfs_client_v1.20.jar', 'junit-4.9.jar', 'lib.lnk'])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\src', ['cn'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\src\\cn', ['itcast'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\src\\cn\\itcast', ['fastdfs'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\src\\cn\\itcast\\fastdfs', ['cliennt'], [])
('C:\\Users\\Administrator\\Desktop\\work\\fastdfsClient\\src\\cn\\itcast\\fastdfs\\cliennt', [], ['FastdfsClientTest.java', 'fdfs_client.conf'])
('C:\\Users\\Administrator\\Desktop\\work\\PythonRedis', ['.idea', '__pycache__'], ['client.conf', 'config$py.class', 'config.py', 'PythonFdfsRedis.py', 'test.py'])
('C:\\Users\\Administrator\\Desktop\\work\\PythonRedis\\.idea', ['inspectionProfiles'], ['misc.xml', 'modules.xml', 'PythonRedis.iml', 'workspace.xml'])
('C:\\Users\\Administrator\\Desktop\\work\\PythonRedis\\.idea\\inspectionProfiles', [], [])
('C:\\Users\\Administrator\\Desktop\\work\\PythonRedis\\__pycache__', [], ['config.cpython-36.pyc'])
~~~
### 2.10 os.environ
用户获取系统信息
~~~
os.environ.keys() 主目录下所有的key
os.environ['HOMEPATH']:当前用户主目录。
~~~
## 3. sys
sys模块提供了一系列有关Python运行环境的变量和函数。
* sys.argv
可以用sys.argv获取当前正在执行的命令行参数的参数列表(list)。
~~~
变量 解释
sys.argv[0] 当前程序名
sys.argv[1] 第一个参数
sys.argv[0] 第二个参数
~~~
~~~
# encoding: utf-8
# filename: argv_test.py
import sys
# 获取脚本名字
print 'The name of this program is: %s' %(sys.argv[0])
# 获取参数列表
print 'The command line arguments are:'
for i in sys.argv:
print i
# 统计参数个数
print 'There are %s arguments.'%(len(sys.argv)-1)
~~~
* sys.platform
获取当前执行环境的平台,如win32表示是Windows 32bit操作系统,linux2表示是linux平台;
* sys.path
path是一个目录列表,供Python从中查找第三方扩展模块。在python启动时,sys.path根据内建规则、PYTHONPATH变量进
## 4. xml
~~~
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year updated_by="Alex" updated_by_tuna="yes">2010</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year updated_by="Alex" updated_by_tuna="yes">2013</year>
<gdppc>59900</gdppc>
<neighbor direction="N" name="Malaysia" />
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year updated_by="Alex" updated_by_tuna="yes">2013</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
<info>
<population>8</population>
<size>960</size>
</info>
</country>
</data>
~~~
#### 4.1 查找
~~~
import xml.etree.ElementTree as etree
# 解析树
parsedTree = etree.parse('xmltest.xml')
root = parsedTree.getroot()
for child in root:
print(child.tag,child.attrib)
for node in child:
print(node.tag,node.text)
# 获取year标签的迭代器
for node in root.iter('year'):
print(node.tag, node.text)
~~~
#### 4.2 修改
~~~
__author__ = 'dailin'
import xml.etree.ElementTree as etree
tree = etree.parse('xmltest.xml')
root = tree.getroot()
# 获取year标签的迭代器
for node in root.iter('year'):
new_year = int(node.text)+1
node.text = str(new_year)
node.set('updated_by_tuna','yes') # 加属性
tree.write('xmltest.xml') # 写回去
# 删除
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output.xml')
~~~
#### 4.3 创建
~~~
__author__ = 'dailin'
import xml.etree.ElementTree as etree
new_xml = etree.Element("personinfolist") # 根节点
# 给new_xml 添加子节点personinfo
personinfo = etree.SubElement(new_xml, "personinfo", attrib={"enrolled": "yes"})
# 给personinfo节点添加子节点name
name = etree.SubElement(personinfo, "name")
name.text = "Alex Li" # name节点文本
age = etree.SubElement(personinfo, "age", attrib={"checked": "no"})
age.text = '56'
sex = etree.SubElement(personinfo, "sex")
sex.text='women'
personinfo2 = etree.SubElement(new_xml, "personinfo", attrib={"enrolled": "no"})
name = etree.SubElement(personinfo2, "name")
name.text = "Oldboy Ran"
age = etree.SubElement(personinfo2, "age")
age.text = '19'
et = etree.ElementTree(new_xml) # 生成文档对象xml_declaration=True xml声明
et.write("createdByTuna.xml", encoding="utf-8", xml_declaration=True)
~~~
得到
~~~
<?xml version='1.0' encoding='utf-8'?>
<personinfolist>
<personinfo enrolled="yes">
<name>Alex Li</name>
<age checked="no">56</age>
<sex>women</sex>
</personinfo>
<personinfo enrolled="no">
<name>Oldboy Ran</name>
<age>19</age>
</personinfo>
</personinfolist>
~~~
## 5. ConfigParser
一,首先说说 所谓 ini 文件以及 ini的文件格式:
ini 文件其实就是所谓的初始化配置文件,一般的格式为:
~~~
[SECTION0] # 相当于一个配置分类
key0 = value0 # 配置项
key1 = value1
[SECTION1]
key0 = value0
key1 = value1
~~~
* 如
~~~
[config]
--oltp-tables-count=10
--oltp-table-size=100000
--num-threads=8
--max-time=600
~~~
二,configparser包
> ConfigParser包是创建一个管理对象,再把配置文件read进去,做了其他操作后,再以打开方式打开文件,写回文件里。(注意!是以打开方式!打开方式!不是追加方式!)
> 因为它本身的机制就是会先把文件复制一份,进行操作后,再整个文件内容写回文件里的。
> 三,相关操作:(一个 item 由 KEY和VALUE组成)
> cfg = configparser.ConfigParser()
> 创建一个管理对象 cfg
> cfg.read(file_path)
> 把一个 ini文件读到cfg中
> se_list = cfg.sections()
> #用一个list存放ini文件中的所有 SECTIONS
> item = cfg.items(SECTION)
> #用一个列表item存放一个SECTION中的所有items(KEY--VALUE)
> cfg.remove_option(se,key)
> #删除一个SECTION中的一个item(以键值KEY为标识)
> cfg.remove_section(se)
> #删除一个SECTION
> cfg.add_section(se)
> #增加一个SECTION
> cfg.set(se,key,value)
> #往一个SECTION中增加一个 item(KEY--VALUE)
> cfg.wrtie(fp)
> #往文件描述符指向的文件中写入修改后的内容
# -*- codeding: utf-8 -*-
import sys
import os
import configparser #导入 configparser包
class client_info(object):
def __init__(self,file):
self.file = file
self.cfg = configparser.ConfigParser() #创建一个管理对象。
def cfg_load(self):
self.cfg.read(self.file) #把文件导入管理对象中,把文件内容load到内存中
def cfg_dump(self):
se_list = self.cfg.sections() #cfg.sections()显示文件中的所有 section
print('==================>')
for se in se_list:
print(se)
print(self.cfg.items(se))
print('==================>')
def delete_item(self,se,key):
self.cfg.remove_option(se,key) #在section中删除一个item
def delete_section(self,se):
self.cfg.remove_section(se) #删除一个section
def add_section(self,se):
self.cfg.add_section(se) #添加一个section
def set_item(self,se,key,value):
self.cfg.set(se,key,value) #往section中添加一个item(一个item由key和value构成)
def save(self):
fd = open(self.file,'w')
self.cfg.write(fd) #在内存中修改的内容写回文件中,相当于保存
fd.close()
if __name__== '__main__':
info = client_info('client.ini')
info.cfg_load()
info.add_section('ZJE')
info.set_item('ZJE','name','zhujunwen')
info.cfg_dump()
info.save()
~~~
import configparser
config = configparser.ConfigParser()
config.read("ConfigParser.ini")
# 获取配置下的配置值,[config] 代表一个section
tableCount = config.get('config','--oltp-tables-count')
tableSize = config.get('config','--oltp-table-size')
threadNum = config.get('config','--num-threads')
maxTime = config.get('config','--max-time')
# 获取配置下的选项
print("table count:" + tableCount)
print("table size:" + tableSize)
print("thred num:" + threadNum)
print("max time:" + maxTime)
mysql = config.options("config")
print("option:" , mysql)
# 获取section下的所有配置项
item = config.items("config")
print("item:",item)
~~~
* 配置文件
~~~
[config]
--oltp-tables-count=10
--oltp-table-size=100000
--num-threads=8
--max-time=600
~~~
## 6. hashlib模块
用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
~~~
import hashlib
m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")
print(m.digest())
m.update(b"It's been a long time since last time we ...")
print(m.digest()) # 2进制格式hash ,用来代表加密后的值
print(len(m.hexdigest())) # 16进制格式hash值,用来代表加密后的值
'''
def digest(self, *args, **kwargs): # real signature unknown
""" Return the digest value as a string of binary data. """
pass
def hexdigest(self, *args, **kwargs): # real signature unknown
""" Return the digest value as a string of hexadecimal digits. """
pass
'''
import hashlib
# ######## md5 ########
hash = hashlib.md5()
hash.update('admin')
print(hash.hexdigest())
# ######## sha1 ########
hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest())
# ######## sha256 ########
hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest())
# ######## sha384 ########
hash = hashlib.sha384()
hash.update('admin')
print(hash.hexdigest())
# ######## sha512 ########
hash = hashlib.sha512()
hash.update('admin')
print(hash.hexdigest())
~~~
还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。
~~~
import hmac
h = hmac.new(b'天王盖地虎', b'宝塔镇河妖')
print h.hexdigest()
~~~
## 7. subprocess模块
subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn*、os.popen*、commands.*等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。
#### 7.1 subprocess.call():
subprocess.call(命令,shell=Boolean)
* 执行命令,并返回执行状态,且值返回执行状态,获取不到命令的执行结果
其中shell参数为False时,命令需要通过列表的方式传入,当shell为True时,可直接传入命令
1. subprocess.call():执行命令,并返回执行状态,其中shell参数为False时,命令需要通过列表的方式传入,(命令拼接)
~~~
>>> a = subprocess.call(['df','-hT'],shell=False)
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 486M 4.0K 486M 1% /dev
tmpfs tmpfs 100M 520K 99M 1% /run
/dev/sda1 ext4 19G 3.3G 15G 19% /
none tmpfs 4.0K 0 4.0K 0% /sys/fs/cgroup
none tmpfs 5.0M 0 5.0M 0% /run/lock
none tmpfs 497M 0 497M 0% /run/shm
none tmpfs 100M 0 100M 0% /run/user
~~~
2. 当shell为True时,可直接传入命令(用主机原生的shell执行命令)
~~~
>>> a = subprocess.call('ls -l',shell=True)
total 160304
drwxrwxr-x 2 tuna tuna 4096 Nov 14 10:06 bzip2-1.0.6
-rw-r--r-- 1 tuna tuna 782025 Jul 31 12:59 bzip2-1.0.6.tar.gz
-rw-r--r-- 1 tuna tuna 721128 Sep 13 22:26 libmysqlclient18_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 1028632 Sep 13 22:26 libmysqlclient-dev_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 9458512 Sep 13 22:26 libmysqld-dev_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 12368 Sep 13 22:26 mysql-client_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 25828 Sep 13 22:26 mysql-common_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 322610 Sep 13 22:26 mysql-community-bench_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 5182472 Sep 13 22:26 mysql-community-client_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 10837528 Sep 13 22:26 mysql-community-server_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 30170644 Sep 13 22:26 mysql-community-source_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 14978548 Sep 13 22:26 mysql-community-test_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 12362 Sep 13 22:26 mysql-server_5.6.38-1ubuntu14.04_amd64.deb
-rw-r--r-- 1 tuna tuna 72775680 Oct 24 09:29 mysql-server_5.6.38-1ubuntu14.04_amd64.deb-bundle.tar
-rw-r--r-- 1 tuna tuna 12368 Sep 13 22:26 mysql-testsuite_5.6.38-1ubuntu14.04_amd64.deb
drwxr-xr-x 17 tuna tuna 4096 Nov 14 10:47 php-5.5.35
-rw-rw-r-- 1 tuna tuna 17774228 Apr 28 2016 php-5.5.35.tar.gz
drwxrwxr-x 3 tuna tuna 4096 Nov 14 11:27 shell
-rw-rw-r-- 1 tuna tuna 5 Nov 15 09:55 test.txt
-rw-r--r-- 1 root root 2694 Feb 15 2016 zabbix-release_3.0-1+trusty_all.deb
>>> print(a)
0
~~~
#### 7.2 subprocess.check_call()
用法与subprocess.call()类似,区别是,当返回值不为0时,直接抛出异常
~~~
>>> a = subprocess.check_call('df -hT',shell=True)
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 94G 64G 26G 72% /
tmpfs tmpfs 2.8G 0 2.8G 0% /dev/shm
/dev/sda1 ext4 976M 56M 853M 7% /boot
>>> print a
0
>>> a = subprocess.check_call('dfdsf',shell=True)
/bin/sh: dfdsf: command not found
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/subprocess.py", line 502, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'dfdsf' returned non-zero exit status 127
~~~
## 7.3 subprocess.check_output():
用法与上面两个方法类似,区别是,如果当返回值为0时,直接返回输出结果,如果返回值不为0,直接抛出异常。需要说明的是,该方法在python3.x中才有。
* 执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res
~~~
>>> res=subprocess.check_output(['ls','-l'])
>>> res
b'total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n'
~~~
## 7.4 subprocess.Popen():
run()
在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要使用到suprocess的Popen()方法。该方法有以下参数:
> args:shell命令,可以是字符串,或者序列类型,如list,tuple。
> bufsize:缓冲区大小,可不用关心
> stdin,stdout,stderr:分别表示程序的标准输入,标准输出及标准错误
> shell:与上面方法中用法相同
> cwd:用于设置子进程的当前目录
> env:用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量
> universal_newlines:不同系统的的换行符不同,当该参数设定为true时,则表示使用\n作为换行符
1. 在/root下创建一个suprocesstest的目录:
在/home/tuna目录下,创建t3目录
~~~
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/tuna',)
~~~
~~~
import subprocess
# 把标准输入流、输出流、错误输出流都交给了subprogress
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# 向输入流写东西
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")
obj.stdin.close() # 关闭输入流
cmd_out = obj.stdout.read() # 读取输出流
obj.stdout.close() # 关闭输出流
cmd_error = obj.stderr.read() # 去取错误流
obj.stderr.close() # 关闭错流
print(cmd_out) # 打印输出
print(cmd_error) # 打印错误输出
~~~
* sudo 密码自动输入
~~~
import subprocess
def mypass():
mypass = 'tuna' #or get the password from anywhere
return mypass
echo = subprocess.Popen(['echo',mypass()],
stdout=subprocess.PIPE, # 把密码输出到了输出流
)
sudo = subprocess.Popen(''sudo mkdir /home/test,
stdin=echo.stdout, # 把密码给输入流
stdout=subprocess.PIPE,
)
end_of_pipe = sudo.stdout
print "Password ok \n Iptables Chains %s" % end_of_pipe.read()
~~~
* 交互
~~~
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write('print 1 \n ')
obj.stdin.write('print 2 \n ')
obj.stdin.write('print 3 \n ')
obj.stdin.write('print 4 \n ')
out_error_list = obj.communicate(timeout=10) # 提交并关闭交互
print out_error_list
~~~
- Docker
- 什么是docker
- Docker安装、组件启动
- docker网络
- docker命令
- docker swarm
- dockerfile
- mesos
- 运维
- Linux
- Linux基础
- Linux常用命令_1
- Linux常用命令_2
- ip命令
- 什么是Linux
- SELinux
- Linux GCC编译警告:Clock skew detected. 错误解决办法
- 文件描述符
- find
- 资源统计
- LVM
- Linux相关配置
- 服务自启动
- 服务器安全
- 字符集
- shell脚本
- shell命令
- 实用脚本
- shell 数组
- 循环与判断
- 系统级别进程开启和停止
- 函数
- java调用shell脚本
- 发送邮件
- Linux网络配置
- Ubuntu
- Ubuntu发送邮件
- 更换apt-get源
- centos
- 防火墙
- 虚拟机下配置网络
- yum重新安装
- 安装mysql5.7
- 配置本地yum源
- 安装telnet
- 忘记root密码
- rsync+ crontab
- Zabbix
- Zabbix监控
- Zabbix安装
- 自动报警
- 自动发现主机
- 监控MySQL
- 安装PHP常见错误
- 基于nginx安装zabbix
- 监控Tomcat
- 监控redis
- web监控
- 监控进程和端口号
- zabbix自定义监控
- 触发器函数
- zabbix监控mysql主从同步状态
- Jenkins
- 安装Jenkins
- jenkins+svn+maven
- jenkins执行shell脚本
- 参数化构建
- maven区分环境打包
- jenkins使用注意事项
- nginx
- nginx认证功能
- ubuntu下编译安装Nginx
- 编译安装
- Nginx搭建本地yum源
- 文件共享
- Haproxy
- 初识Haproxy
- haproxy安装
- haproxy配置
- virtualbox
- virtualbox 复制新的虚拟机
- ubuntu下vitrualbox安装redhat
- centos配置双网卡
- 配置存储
- Windows
- Windows安装curl
- VMware vSphere
- 磁盘管理
- 增加磁盘
- gitlab
- 安装
- tomcat
- Squid
- bigdata
- FastDFS
- FastFDS基础
- FastFDS安装及简单实用
- api介绍
- 数据存储
- FastDFS防盗链
- python脚本
- ELK
- logstash
- 安装使用
- kibana
- 安准配置
- elasticsearch
- elasticsearch基础_1
- elasticsearch基础_2
- 安装
- 操作
- java api
- 中文分词器
- term vector
- 并发控制
- 对text字段排序
- 倒排和正排索引
- 自定义分词器
- 自定义dynamic策略
- 进阶练习
- 共享锁和排它锁
- nested object
- 父子关系模型
- 高亮
- 搜索提示
- Redis
- redis部署
- redis基础
- redis运维
- redis-cluster的使用
- redis哨兵
- redis脚本备份还原
- rabbitMQ
- rabbitMQ安装使用
- rpc
- RocketMQ
- 架构概念
- 安装
- 实例
- 好文引用
- 知乎
- ACK
- postgresql
- 存储过程
- 编程语言
- 计算机网络
- 基础_01
- tcp/ip
- http转https
- Let's Encrypt免费ssl证书(基于haproxy负载)
- what's the http?
- 网关
- 网络IO
- http
- 无状态网络协议
- Python
- python基础
- 基础数据类型
- String
- List
- 遍历
- Python基础_01
- python基础_02
- python基础03
- python基础_04
- python基础_05
- 函数
- 网络编程
- 系统编程
- 类
- Python正则表达式
- pymysql
- java调用python脚本
- python操作fastdfs
- 模块导入和sys.path
- 编码
- 安装pip
- python进阶
- python之setup.py构建工具
- 模块动态导入
- 内置函数
- 内置变量
- path
- python模块
- 内置模块_01
- 内置模块_02
- log模块
- collections
- Twisted
- Twisted基础
- 异步编程初探与reactor模式
- yield-inlineCallbacks
- 系统编程
- 爬虫
- urllib
- xpath
- scrapy
- 爬虫基础
- 爬虫种类
- 入门基础
- Rules
- 反反爬虫策略
- 模拟登陆
- problem
- 分布式爬虫
- 快代理整站爬取
- 与es整合
- 爬取APP数据
- 爬虫部署
- collection for ban of web
- crawlstyle
- API
- 多次请求
- 向调度器发送请求
- 源码学习
- LinkExtractor源码分析
- 构建工具-setup.py
- selenium
- 基础01
- 与scrapy整合
- Django
- Django开发入门
- Django与MySQL
- java
- 设计模式
- 单例模式
- 工厂模式
- java基础
- java位移
- java反射
- base64
- java内部类
- java高级
- 多线程
- springmvc-restful
- pfx数字证书
- 生成二维码
- 项目中使用log4j
- 自定义注解
- java发送post请求
- Date时间操作
- spring
- 基础
- spring事务控制
- springMVC
- 注解
- 参数绑定
- springmvc+spring+mybatis+dubbo
- MVC模型
- SpringBoot
- java配置入门
- SpringBoot基础入门
- SpringBoot web
- 整合
- SpringBoot注解
- shiro权限控制
- CommandLineRunner
- mybatis
- 静态资源
- SSM整合
- Aware
- Spring API使用
- Aware接口
- mybatis
- 入门
- mybatis属性自动映射、扫描
- 问题
- @Param 注解在Mybatis中的使用 以及传递参数的三种方式
- mybatis-SQL
- 逆向生成dao、model层代码
- 反向工程中Example的使用
- 自增id回显
- SqlSessionDaoSupport
- invalid bound statement(not found)
- 脉络
- beetl
- beetl是什么
- 与SpringBoot整合
- shiro
- 什么是shiro
- springboot+shrio+mybatis
- 拦截url
- 枚举
- 图片操作
- restful
- java项目中日志处理
- JSON
- 文件工具类
- KeyTool生成证书
- 兼容性问题
- 开发规范
- 工具类开发规范
- 压缩图片
- 异常处理
- web
- JavaScript
- 基础语法
- 创建对象
- BOM
- window对象
- DOM
- 闭包
- form提交-文件上传
- td中内容过长
- 问题1
- js高级
- js文件操作
- 函数_01
- session
- jQuery
- 函数01
- data()
- siblings
- index()与eq()
- select2
- 动态样式
- bootstrap
- 表单验证
- 表格
- MUI
- HTML
- iframe
- label标签
- 规范编程
- layer
- sss
- 微信小程序
- 基础知识
- 实践
- 自定义组件
- 修改自定义组件的样式
- 基础概念
- appid
- 跳转
- 小程序发送ajax
- 微信小程序上下拉刷新
- if
- 工具
- idea
- Git
- maven
- svn
- Netty
- 基础概念
- Handler
- SimpleChannelInboundHandler 与 ChannelInboundHandler
- 网络编程
- 网络I/O
- database
- oracle
- 游标
- PLSQL Developer
- mysql
- MySQL基准测试
- mysql备份
- mysql主从不同步
- mysql安装
- mysql函数大全
- SQL语句
- 修改配置
- 关键字
- 主从搭建
- centos下用rpm包安装mysql
- 常用sql
- information_scheme数据库
- 值得学的博客
- mysql学习
- 运维
- mysql权限
- 配置信息
- 好文mark
- jsp
- jsp EL表达式
- C
- test