博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自动化运维学习--python
阅读量:7019 次
发布时间:2019-06-28

本文共 30301 字,大约阅读时间需要 101 分钟。

hot3.png

环境搭建

单机环境搭建

安装python

apt-get install python python-dev python-setuptools

安装pip

apt-get install python-pip

简单主机信息

说明:主要参考网站

安装psutil

pip install psutil

cpu

cpu times

import psutilcputimes = psutil.cpu_times()psutil.cpu_times().user

结果如下:

scputimes(user=1751.49, nice=57.5, system=1126.75, idle=61666.12, iowait=745.43, irq=0.0, softirq=1.58, steal=0.0, guest=0.0, guest_nice=0.0)

解释: user:用户cpu time; nice: ; system:系统cpu time; idle:cpu空闲状态cpu time; iowait:io等待时间;

取出cpu_times()中的参数,例如用户cpu时间

psutil.cpu_times().user

获取物理cpu个数

psutil.cpu_count(lgicol=False)

内存和交换分区

内存信息

psutil.virtual_memory()

结果如下:

svmem(total=8288972800L, available=6737719296L, percent=18.7, used=3927216128L, free=4361756672L, active=2380361728, inactive=1244004352, buffers=150831104L, cached=2225131520)

解释 total: 所有物理内存 available: 实际上可以立刻使用的内存(单位是byte) percent:内存使用的内存(total - available) / total * 100. used: 使用的内存 free: 空闲内存 Platform-specific fields:特定平台的属性

active: (UNIX): memory currently in use or very recently used, and so it is in RAM. inactive: (UNIX): 未被使用的内存 buffers: (Linux, BSD): 文件缓存 cached: (Linux, BSD): 缓存 wired: (BSD, OSX):常驻内存 在RAM中的 shared: (BSD): 共享内存

交换分区

psutil.virtual_memory()

结果: sswap(total=4999606272L, used=0L, free=4999606272L, percent=0.0, sin=0, sout=0)

硬盘

分区信息

psutil.disk_partitions()

结果: [sdiskpart(device='/dev/sda4', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro')]

使用信息

psutil.disk_usage('/')

结果: sdiskusage(total=202632327168, used=6518771712, free=185796829184, percent=3.2)

进程信息

pid=3923p = psutil.Process(pid)#print process namep.name()#print process execuable file pathp.exe()#print process current work directoryp.cwd()#print process children processp.get_children()

net IO

psutil.net_io_counters()

结果: snetio(bytes_sent=4469434, bytes_recv=64367107, packets_sent=40469, packets_recv=53242, errin=0, errout=0, dropin=0, dropout=0)

Ip information

IPy模块处理IP信息

  1. 安装sudo pip install Ipy
  2. IPy包中的IP类 2.1 列出网段中的IP数目:
ip = IP('8.8.8.8')    for i in ip:    	print (x)

2.2 IP转换

ip.int()#将IP转为整数型    ip.strHex()#将IP转为十六进制    ip.strBIn()#将IP转为二进制

2.3 将十六进制的IP地址转换成为常见的淀粉十进制

print(IP(0x8080808))#输出为8.8.8.8

2.4 生成子网掩码

IP('8.8.8.8').make_net('255.255.255.0)    IP('8.8.8.8/255.255.255.0',make_net=True)

dns information

  1. 安装dnspython sudo pip install dnspython
  2. 域名解析知识清理:
    • A记录:域名转为IP地址
    • MX记录:邮件交换记录,定义邮件服务器的域名信息
    • CNAME记录:实现域名见的映射。别名记录
    • NS记录:标记区域的域名服务器授权服务器和授权子域
    • PTR记录:反响解析,与A记录相反
    • SOA记录:标记一个其实授权去的定义

A记录解析过程:

import dns.resolver    domain = "www.google.com"    A = dns.resolver.query(domain,'A')    for x in A.response.answer:    	for i in x:        	print (i.address)

MX记录解析

#! /usr/bin/python	import dns.resolver	domain="163.com"	MX = dns.resolver.query(domain,'MX')	for i in MX:		print i.preference, i.exchange

NS记录解析

#! /usr/bin/python	import dns.resolver	domain= "baidu.com"	NC = dns.resolver.query(domain,'Ns')	for x in NC.response.answer:		for i in x.items:			print i.to_text()

CNAME记录解析

#!/usr/bin/python	import dns.resolver	domain = "www.baidu.com"	cname = dns.resolver.query(domain,'CNAME')	for i in cname.response.answer:        for j in i.items:        	print (j.to_text())

实例:DNS轮循服务业务监控

#! /usr/bin/pythonimport dns.resolverimport osimport httplibiplist=[]domain = "baidu.com"def getIpList(domain=""):        try:                A = dns.resolver.query(domain,'A')        except Exception,e:                print "dns resolver error:"+str(e)                return        for x in A.response.answer:                for i in x.items:                        iplist.append(i.address)        return Truedef checkIp(ip):        checkurl = ip + ":80"        getcontent = ""        httplib.socket.setdefaulttimeout(5)        conn = httplib.HTTPConnection(checkurl)        try:                conn.request("GET","/",headers={"Host":domain})                r = conn.getresponse()                getcontent = r.read(15)        finally:                if getcontent == "":                        print ip+"[OK]"                else:                        print ip+"[Error]"                        print getcontent+"\n"if __name__ =="__main__":        if(getIpList(domain) and len(iplist)>0):                for ip in iplist:                        checkIp(ip)        else:                print "dns resolver error."

业务服务质量监控

文本内容对比工具

#!/usr/bin/python#coding:utf-8import difflibimport systry:        firstfile = sys.argv[1]#python 的参数是从一开始的        secondfile = sys.argv[2]except Exception,e:        print ("Error:"+ str(e))        print ("Usage: compare.py file1 file2")        sys.exit()def readfile(path):        try:                filehandle = open(path,'r')                text = filehandle.read().splitlines()                filehandle.close()                return text        except IOError as error:                print ("Read file error:" + str(error))                print ("Usage: compare.py file1 file2")                sys.exit()if(firstfile =="" or secondfile ==""):        print ("Usage: compare.py file1 file2")        sys.exit()file1lines = readfile(firstfile)file2lines = readfile(secondfile)diff = difflib.HtmlDiff()print diff.make_file(file1lines,file2lines)

文件目录差异对比工具

python自带的filecmp满足需求。

filecmp模块常见的方法的说明

filecmp常见的方法有:cmp(单文件对比),cmpfiles(多文件对比),dircmp(目录对比) + filecmp.cmp(f1,f2[,shallow=True]):对比文件f1和f2是否相同,相同就返回True,不同为False。shallow为可选的参数,默认为True。shallow为True时表示根据文件的属性值(最后修改时间,作者,状态改变时间等)进行对比判断两文件是否相同;shallow为false时,同时对比os.stat()和对比两文件的内容判断是否相同。 + filecmp.cmpfiles(dir1,dir2[,shallow=True]).对比dir1和dir2给定的文件清单。该方法返回三个列表:匹配,不匹配,错误(目录中不存在,读写权限不够,或其他原因导致的不能比较的清单)。 + filecmp.dircmp(a,b[,ignore[,hide]])创建一个目录比较对象,a,b,是参加比较的目录名,ignore是忽略的文件列表,并默认为['RCS','CVS',tags'];hide表示隐藏的文件爱你列表,默认为[os.curdir,os.pardir]。dircmp类可以获得目录比较的详细信息,如只有a含有的文件。dircmp提供3个输出报告的方式: * report():比较当前目录的内容 * report_partial_closure():比较当前目录和第一级子目录的内容 * report_full_clourse():递归比较所有的文件

校验源与备份目录的差异

python shutil 模块常见函数:

  • copyfile( src, dst) 从源src复制到dst中去。当然前提是目标地址是具备可写权限。抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉
  • copymode( src, dst) 只是会复制其权限其他的东西是不会被复制的
  • copystat( src, dst) 复制权限、最后访问时间、最后修改时间
  • copy( src, dst) 复制一个文件到一个文件或一个目录
  • copy2( src, dst) 在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西
  • copy2( src, dst) 如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;如果是不在相同的文件系统的话就是做move操作
  • copytree(olddir,newdir,True/Flase) 把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接

使用python发送邮件

简单邮件发送

1.smtplib.SMTP(host,port[,local_hostname[,timeout]])构造smtp类,每个参数的含义:

  • host:邮件服务器地址
  • port:邮件服务器端口
  • local_hostname:在本地主机的FQDN发送HELO/EHLO(标识身份)指令
  • timeout:超时时间,单位s(秒)
#! /usr/bin/python# coding:utf-8import smtplibimport stringHOST = "smtp.google.com"SUBJECT = "TEST EMAIL"TO = "980673553@qq.com"FROM = "hgfgooda@gmail.com"text = "this is the mail body main test!"other = "other info"		#BODY中的other如果包含字符,则收到的邮件中没有内容,为什么?这个字段是什么意思?BODY = string.join(    (        "From: %s" % FROM,        "TO: %s" % TO,        "Subject: %s" % SUBJECT,        other,        text    ), "\r\n")server = smtplib.SMTP()server.connect(HOST, 25)server.starttls()server.login("hgfgooda@gmail.com", "password")server.sendmail(FROM, TO, BODY)server.quit()

定制丰富内容的邮件

1.使用html编写邮件内容

#! /usr/bin/python# coding:utf-8import smtplibfrom email.mime.text import MIMETextHOST = "smtp.qq.com"SUBJECT = u"官方流量数据报表"FROM = "980673553@qq.com"TO = "hgfgoodcreate@163.com"msg = MIMEText("""
*官网数据
  1. 日访问量:152433 访问次数:23651 页面浏览量:45123 点击数:545122 数据流量:504Mb
  2. 状态码信息:
  3.    500:105 404:3264 503:214
  4. 浏览器浏览信息:
  5.    IE:50% firefox:10% chrome:30% other:10%
  6. 页面信息:
  7.    /index.php 42153
       /view.php 21451
       /login.php 5122
""", "html", "utf-8")msg['Subject'] = SUBJECTmsg['From'] = FROMmsg['TO'] = TOtry: server = smtplib.SMTP() server.connect(HOST, "25") server.starttls() server.login("980673553@qq.com", "password") server.sendmail(FROM, TO, msg.as_string()) server.quit() print("邮件发送成功!")except Exception, e: print("失败!原因:"+str(e))

注意点 在使用email.mime.text.MIMEText对象的时候,需要将MIMEText对象的内容,编码和内容使用的语言交代清楚。

2.在邮件中添加图片

  • 定义一个email.mime.multipart.MIMEMultipart对象
  • 使用MIMEMultipart对象的attach函数,将html内容嵌入到邮件中,其中使用contentID来访问嵌入到邮件中的图片信息
  • 使用MIMEImage对象,将图片文件从本地以二进制的形式读入到内存,并用图像文件的二进制序列初始化MIMEImage对象,使用MIMEImageadd_header()方法给MIMEImage对象设置contentID
  • 使用MIMEMultipart对象的attach函数,将MIMEImage对象嵌入到邮件中
#! /usr/bin/python# coding:utf-8import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.image import MIMEImagefrom email.mime.text import MIMEText__author__ = 'hgf'HOST = "smtp.qq.com"SUBJECT = u"业务性能数据表"FROM = "980673553@qq.com"TO = "hgfgoodcreate@163.com"def addimg(src, imgid):    fp = open(src, 'rb')    msgImg = MIMEImage(fp.read())    fp.close()    msgImg.add_header('Content-ID', imgid)    return msgImg# 使用related定义内嵌资源msg = MIMEMultipart('related')msgtext = MIMEText("""
*官网logo
""", "html", "utf-8")msg.attach(msgtext)msg.attach(addimg("/home/hgf/Pictures/program/logo/1.PNG", "p1"))msg.attach(addimg("/home/hgf/Pictures/program/logo/2.PNG", "p2"))msg.attach(addimg("/home/hgf/Pictures/program/logo/3.PNG", "p3"))msg.attach(addimg("/home/hgf/Pictures/program/logo/4.PNG", "p4"))msg['Subject'] = SUBJECTmsg['From'] = FROMmsg['To'] = TOtry: server = smtplib.SMTP() server.connect(HOST, 25) server.starttls() server.login(FROM, "password") server.sendmail(FROM, TO, msg.as_string()) server.quit() print("发送成功")except Exception, e: print("失败!原因:"+str(e))

3.在邮件中添加附件

  • 初始化MIMEText对象作为附件:将本地的文件以读取二进制的方式,将文件内容用于初始化MIMEText对象,设置MIMEText的格式为base64编码,文字编码为utf-8
  • 设置MIMEText实例的Content-Type属性为application/octet-stream(专用来说明不知道文件类型的二进制流),
  • 设置MIMEText实例的Content-Disposition属性为attachment;filename=文件名,使得附件可以用来下载
  • MIMEText实例attach到MIMEMultipart对象中
#! /usr/bin/python# coding:utf-8import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.image import MIMEImagefrom email.mime.text import MIMEText__author__ = 'hgf'HOST = "smtp.qq.com"SUBJECT = u"业务性能数据表"FROM = "980673553@qq.com"TO = "hgfgoodcreate@163.com"def addimg(src, imgid):    fp = open(src, 'rb')    msgImg = MIMEImage(fp.read())    fp.close()    msgImg.add_header('Content-ID', imgid)    return msgImgmsg = MIMEMultipart('related')msgtext = MIMEText("""官网业务平均时延图表:
详细内附件图表
""", "html", "utf-8")msg.attach(msgtext)msg.attach(addimg("/home/hgf/Pictures/program/logo/1.PNG", "p1"))attach = MIMEText(open("/home/hgf/test.xlsx", 'rb').read(), "base64", "utf-8")attach["Content-type"] = "application/octet-stream"# 指定文件格式类型# 指定ContentDisposition 属性值为attachement 则会出现自爱在保存对话框# qqmail使用gb18030编码,为保证中文不会乱码,对文件名进行编码转换attach["Content-Disposition"] = "attachment;filename=\"excel.xlsx\"".decode("utf-8").encode("gb18030")msg.attach(attach)msg['Subject'] = SUBJECTmsg['From'] = FROMmsg['To'] = TOtry: server = smtplib.SMTP() server.connect(HOST, 25) server.starttls() server.login(FROM, "passwprd") server.sendmail(FROM, TO, msg.as_string()) server.quit() print("发送成功!")except Exception, e: print("发送失败:"+str(e))

web服务器性能

安装pycurl

  1. 安裝curl:sudo apt-get install curl
  2. 安裝openssl:apt-get install openssl
  3. 安裝pycurl:sudo pip install pycurl

TIPS:

In [2]: pycurl.versionOut[2]: 'PycURL/7.19.5.1 libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3'

安裝问题

  1. 错误__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory
Downloading/unpacking pycurl  Running setup.py egg_info for package pycurl    Traceback (most recent call last):      File "
", line 16, in
File "/tmp/pip-build-root/pycurl/setup.py", line 563, in
ext = get_extension() File "/tmp/pip-build-root/pycurl/setup.py", line 368, in get_extension ext_config = ExtensionConfiguration() File "/tmp/pip-build-root/pycurl/setup.py", line 65, in __init__ self.configure() File "/tmp/pip-build-root/pycurl/setup.py", line 100, in configure_unix raise ConfigurationError(msg) __main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory Complete output from command python setup.py egg_info: Traceback (most recent call last): File "
", line 16, in
File "/tmp/pip-build-root/pycurl/setup.py", line 563, in
ext = get_extension() File "/tmp/pip-build-root/pycurl/setup.py", line 368, in get_extension ext_config = ExtensionConfiguration() File "/tmp/pip-build-root/pycurl/setup.py", line 65, in __init__ self.configure() File "/tmp/pip-build-root/pycurl/setup.py", line 100, in configure_unix raise ConfigurationError(msg)__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory

解决方案

在debian系列操作系统中需要安装openssl

sudo apt-get install libcurl4-openssl-dev

简单使用curl

#! /usr/bin/python# coding:utf-8import pycurl__author__ = 'hgf'c = pycurl.Curl()c.setopt(pycurl.URL, "http://www.baidu.com")c.setopt(pycurl.CONNECTTIMEOUT, 5)c.setopt(pycurl.NOPROGRESS, 0)c.setopt(pycurl.FORBID_REUSE, 1)f = open("a.txt",'wb')c.setopt(pycurl.WRITEHEADER, f)c.setopt(pycurl.WRITEDATA, f)c.setopt(pycurl.DNS_CACHE_TIMEOUT, 30)c.perform()c.close()

** 注意: ** 使用pycurl必须定义pycurl.URL的值,必须调用perform函数使pycurl生效,并且一般需要定义处理pycurl返回的结果。

使用curl探测web服务质量

#! /usr/bin/python# coding:utf-8import pycurlimport osimport sys__author__="hgf"URL = "http://www.baidu.com"c = pycurl.Curl()c.setopt(pycurl.URL, URL)c.setopt(pycurl.CONNECTTIMEOUT, 5)c.setopt(pycurl.TIMEOUT, 5)c.setopt(pycurl.NOPROGRESS, 1)c.setopt(pycurl.FORBID_REUSE, 1)c.setopt(pycurl.DNS_CACHE_TIMEOUT, 30)c.setopt(pycurl.MAXREDIRS, 1)indexfile = open(os.path.dirname(os.path.realpath(__file__))+"/content.txt",'wb')c.setopt(pycurl.WRITEHEADER, indexfile)c.setopt(pycurl.WRITEDATA, indexfile)try:	c.perform()except Exception, e:	print ("error:"+str(e))	indexfile.close()	c.close()	sys.exit()NAMELOOKUP_TIME = c.getinfo(c.NAMELOOKUP_TIME)CONNECT_TIME = c.getinfo(c.CONNECT_TIME)PRETRANSFER_TIME = c.getinfo(c.PRETRANSFER_TIME)STARTTRANSFER_TIME = c.getinfo(c.STARTTRANSFER_TIME)TOTAL_TIME = c.getinfo(c.TOTAL_TIME)HTTP_CODE = c.getinfo(c.HTTP_CODE)SIZE_DOWNLOAD = c.getinfo(c.SIZE_DOWNLOAD)HEADER_SIZE = c.getinfo(c.HEADER_SIZE)SPEED_DOWNLOAD = c.getinfo(c.SPEED_DOWNLOAD)print "HTTP状态码:%s" % HTTP_CODEprint "DNS解析时间:%.2f ms" % (NAMELOOKUP_TIME*1000)print "建立连接时间:%.2f ms" % (CONNECT_TIME*1000)print "准备传输时间: %.2f ms" % (PRETRANSFER_TIME*1000)print "传输开始时间:%.2f ms" % (STARTTRANSFER_TIME*1000)print "传输结束时间: %.2f ms" % ((TOTAL_TIME - STARTTRANSFER_TIME)*1000)print "下载数据包大小: %.2f bytes/s" % SIZE_DOWNLOADprint "HTTP 头部大小: %.2f byte" % HEADER_SIZEprint "下载速度:%.2f bytes/s" % SPEED_DOWNLOADindexfile.close()c.close()

定制报表

python处理excel

安装slsxwriter

pip install XlsxWriter

XlsxWriter常见方法的使用

  1. Workbook类

    • Worlbook对象代表了Excel的整个文件,并且存储在磁盘上,
    • 构造方法:Workbook(filename[, option])
    • 主要的方法:
      • add_Worksheet([sheetname]):添加一个新的工作表,不定义sheetname时,默认为sheet[工作表序号]
      • add_format([proprties]):创建一个新的格式对象来格式化单元格,参数proprties为dict类型, 指定一个单元格属性的字典。
        • 例如:workbook.add_format({'bold':True}),设置加粗的单元格。
        • 上述设置等价方式:bold = workbook.add_format()bold.set_bold()
      • add_chart(options):在工作表中创建一个图表对象,内部通过insert_chart()实现。option为dict类型。
      • close():关闭工作表文件。
  2. WorkSheet类

    • write(row, col, *args):将普通数据写道单元格中,其中(row, col)为单元格在表格中的位置,起始位置为(0,0);×args为要写入的数据内容, 可以为数字,字符串,格式对象。
    • set_row(row, height, cell_format, option):设置行单元格的属性,row指定行位置;height设置行高,单位为像素;cell_formatformat类型,指定格式对象;参数option是dict类型,设置行hiden(隐藏),level(组合分级),collapsed(折叠)。
    • set_column(first_col, last_col, wodth, cell_format, option):设置一列或多列单元格属性。参数wodth(float类型)设置列宽,cell_formatoptions同上。
    • insert_image(row, col, image[, option]):插入图片到指定单元格,支持PNG,JPEG,BMP等图片格式。image(String类型)表示图片的路径。options(dist类型):制定图片的位置、比例、链接URL等。
      • 例如:worksheet.insert_image('B5', 'img/python-logo.jpg', {'url':''})`
  3. Chart类

    • 支持的图表类型包括面积,条形图,柱形图,饼状图,散点图,shares,雷达。
    • 图表通过worksheetadd_chart方法创建图表。chart = worksheet.add_chart({type,'column'})创建一个柱形图。

图表类型说明: |类型关键字|图表类型| |--------|-------| |area|面积样式图表| |bar|条形态| |column|柱形图| |line|条形图| |pie|饼状图| |scatter|散点图| |stock|shares图| |radar|雷达图|

+ 通过`insert_chart()`方法将图标插入到指定的地方。+ 主要的方法:	- `chat.add_series(options)`:添加一个数据系列到图表。		* 例子:		```python		chat.add_series({ 		   	'categories':	'=Sheet1!$a$1:$A$5', 	       'values':		'=Sheet1!$B$1:$B$5', 	       'line':			{'color':'red'},	    })
>说明:>`add_series`最长见的option是>`categories`:表示图表标签的范围[将表格中的对应位置的内容作为图表的横轴];>`value`:图表的数据范围[表格中的范围内的数据作为画图的数据]>`line`:图标的线条属性,包括颜色,宽度等。>`name`:图例项,[一个图的多种内容的区分]		- `set_x_axis(options)`:设置X轴选项,			* 例子			```python            char.set_x_axis({            	'name':	'Earning_per_!Quater',#设置X轴标题名字                'name_font':	{'size':14, 'bold':True},#设置X轴标题字体                'num_foont':	{'italic':True},#设置X轴数字字体            })
- `set_size(options)`:设置图表大小。例如`chart.set_size({'width':720, 'height':576})`	- `set_title`:设置图表的标题。`chart.set_title({'name':'Year End Result'})`	- `set_styke(style_id))':`style_id`为不同数字代表不同的样式。	- `set_table(options)`:设置X轴为数字表格样式

实例:定制自动化业务流量报表

python与rrdtool结合

安装rrdtool

pip install python-rrdtool

可能的错误:

  1. I found a copy of pkgconfig, but there is no libxml-2.0.pc file around. You may want to set the PKG_CONFIG_PATH variable to point to its location. 原因:没有安装libxml 解决方案:sudo apt-get install libxml2 sudo apt-get install libxml2-dev
  2. 出现cannot find -lrrd 原因:库文件没有导入到ld检索目录中,或者是库文件是在so后面加上了序号,导致找不到库文件 解决方案:只需要使用ln命令,将带号码的so文件软链接到不带序号的库文件,如sudo ln -sv librrd.so.4 librrd.so

python与系统安全

病毒扫描

nmap端口扫描

在使用python-nmap前,需要在操作系统上安装namp:yum install namp

  1. 模块说明
  • PortScanner类【nmap端口扫描的封装】
    • scan(self, host='127.0.0.1', ports=None, arguments='-sV'):制定扫描的主机端口,nmap命令行扫描的参数。其中host的参数形式可以是域名('scanne.nmap.org'),网段('192.168.0-255.1-127'或'192.168.128.20/20'),IP地址;ports表示扫描的端口,可以用22,53,110,143-4564来表示;arguments为字符串类型,是nmap命令行下的扫描参数。
    • comman_line(self):返回扫描方法对应的命令行下面的nmap命令。
    • scaninfo(self):扫描的信息,字典类型
    • all_hosts(self):返回nmap扫描的主机清单,格式为list
    • hostname(self):返回扫描对西那个的名字
    • state(self):返回扫描对象的状态(主要包括up,down,unknow,skipped)
    • all_protocals(self):返回扫描协议
    • all_tcp(self):返回TCP协议端口
    • tcp(self,port):返回TCP协议port端口的信息
  • PortScannerHostDict类【存储与访问主机的扫描结果】
  1. 示例
#! /usr/bin/python# -*- coding:utf-8 -*-import nmapimport sys__author__ = 'hgf'def detailinfo(hosts, ports):    '''    使用nmap test hosts中的所有的ports,并输出详细的信息    :param hosts: 所有主机    :param ports:所有端口号    :return:    '''    try:        nm.scan(hosts = hosts, arguments='-v -sS -p'+ports)    except Exception,e:        print("Scan error:"+ str(e))    for host in nm.all_hosts():        print('-------------------------------------------------------------------------------------------------------')        print('Host: %s (%s)'% (host, nm[hosts].hostname()))        print('State: %s' % nm[host].state())        for proto in nm[host].all_protocols():            print('------------------------------------------------')            print('Protocal: %s'% proto)            iport = nm[host][proto].keys()            iport.sort()            for port in iport:                print('Port: %s \tstate: %s' %(port, nm[host][proto][port]['state']))def printcsv(nm):    '''    将nmap的结果以excel表的格式输出    :param nm: namp实例    :return:    '''    print('-----------------------------------------------------------------------------------------------------------')    print('print result as csv')    print(nm.csv())def pingsweep(hosts,ports):    '''    根据ports端口,查询网段内存活主机    :param hosts:网段    :param ports:端口    :return:    '''    nm.scan(hosts=hosts, arguments='-n -sP -PE -PA'+ports)    host_list=[(x,nm[x]['status']['state']) for x in nm.all_hosts()]    for host, state in host_list:        print('{0}:{1}'.format(host,state))def call_back(host, scan_result):    print("----------------------------------")    print host, scan_resultdef arsynNmap(hosts):    '''    异步Nmap    :param hosts:    :return:    '''    nma = nmap.PortScannerAsync()    nma.scan(hosts=hosts, arguments='-sP', callback=call_back)    while nma.still_scanning():        print('wait')        nma.wait(2)        # do some other thingsscan_row=[]input_data = raw_input("Please input hosts and ports:")scan_row = input_data.split(' ')if len(scan_row)!=2:    print("input error, example input \"192.168.1.0/24 80,433-560\"")    sys.exit(0)hosts = scan_row[0]ports = scan_row[1]try:    nm = nmap.PortScanner()except nmap.PortScannerError:    print("Nmap not found ", sys.exc_info()[0])    sys.exit(0)except:    print("Unexcepted error!")    sys.exit(0)arsynNmap(hosts)

pexpect

纯python编写的系统批量运维管理器。

安装

sudo pip install pexpect

pexpect使用

pexpect主要有两大功能:

run方法

run方法主要替代原来的'os.system()'

spawn 类

spawn主要实现了自动交互的功能。

注意: spawn;类不会解析shell命令中的元字符,包括重定向>,管道|,或者是通配符*,但是我们可以使用给/bin/bash传递参数的形式使用元字符。 例如:pexpect.spawn('/bin/bash -c "ls -al | grep LOG > logs.txt"')

  • pexpect日志输出到文件:``` child = pexpect.spawn('some_command') fout = file('mylog.txt','w') child.logfile(fout)
* pexpect日志输出到标准输出流:```child = pexpect.spawn('some_command')child.logfile = sys.stout

使用pexpect的注意事项

  1. 注意使用scp时,传送文件的权限,当使用pexpect的命令中,包含用scp传送权限比较高,或者传送文件的所有者不是运行pexpect程序的人的时候,需要考虑处理文件权限的问题。特别是传送系统配置文件时,就算root运行程序也不能传送文件成功。
  2. 一般的使用步骤:
  • 保证目录下有那个文件
  • 保证执行py的用户有那个传送文件的权限

paramiko

基于python实现的SSH2安全连接,支持认证及密钥方式,可以实现远程命令执行,文件传输,中间ssh代理等。

安装paramiko

sudo pip install paramiko

paramiko的简单test

#/usr/bin/python# coding:utf-8import paramikoimport sys__author__='hgf'try:    data =  raw_input("Please input hostname username and password:").split()    if len(data)!=3:        print("input error! make sure your input like \"192.168.1.1 root 123456\"")        sys.exit(0)except Exception,e:    print("Exception occourred!")    print (str(e))hostname = data[0]username = data[1]password = data[2]paramiko.util.log_to_file('sys.log')ssh = paramiko.SSHClient()ssh.load_system_host_keys()ssh.connect(hostname = hostname, username = username, password = password)stdin, stdout, stderr = ssh.exec_command('free -m')print stdout.read()ssh.close()

paramiko的核心组件

  1. SSHClient
  • connect方法

    • connect(self, hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow=True, look_for_keys=True. compress=False)
    • 各个参数的含义:
      • hostname:(str类型)目的主机
      • port:(int类型)端口号
      • username:(str类型)目的主机的用户名(默认与当前的本地主机用户名相同)
      • password:(str类型)密码用于身份校验或解锁私钥
      • pkey:(PKey类型)私钥方式进行验证
      • key_filename:(list(str))或者是str类型)一个文件名或是文件列表,用于私钥的身分验证
      • timeout:(int类型)设定链接的超时信息
      • allow_agent:(bool类型)设置为False时,禁止连接到SSH代理
      • look_for_keys:(bool类型)False时禁止在~/.ssh目录中搜索私钥文件
      • compress:(bool类型) 设置为True打开压缩
  • exec_command方法:远程执行命令的方法,输入输出流为标准的的输入输出流,错误流(stdin,stdout,stderr)

    • exec_command(self, command, bufsize=-1)
    • command:(str类型),执行的命令
  • load_system_host_keys方法,指定远程主机的公钥记录文件(默认为~/.ssh/known_hosts

    • load_system_host_keys(self, filename=None)
  • set_missing_host_key_policy方法:设置远程主机没有本地主机密钥或Hostskye的情况时的策略,目前支持3种。

    • AutoAddPolicy,自动添加主机名及主机密钥到本地hostsKeys对象(具体时那个文件????),并保存。不依赖于load_system_host_keys()的配置。
    • RejectPolicy,自动拒绝未知主机名和密钥, 依赖load_system_host_keys的配置。
    • WarningPolicy,用于记录一个位置的主机名和密钥的python警告,并接受。功能上与AutoAddPolicy相似但是未知主机会有警告。

    使用方法:

     

    ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

     

说明: 可以通过SSHClient对象的invoke_shell方法获取paramikoChannel,开启命令调用.即使用Channelsend()方法,可以发送一系列的shell命令。例如:

 

ssh = paramiko.SSHClient() ssh.connect(hostname,username,password) channel = ssh.invoke_shell() channel.send('ls')

 
  1. SFTPClient
  • from_transport方法:创建爱哪一个已经连通的SFTP客户端通道

    • from_transport(self, t)
    • 参数t表和isyige已经验证过的传输对象(paramiko.Transport对象)
    • 例子:```python t = paramiko.Transport(('192.168.1.22',22)) t.connect(username='root', password = '123456') sftp = paramiko.SFTPClient.from_transport(t)
     
  • put方法:上传本地文件到远程SFTP服务端

    • put(self, localpath, remotepath, callback=None, confirm=True)
    • 参数说明:
      • localpath: (str类型)需要上传的本地文件
      • remotepath:(str类型)远程路径
      • callback(function (int, int)):获取已经接收的字节数及宗的传输字节数, 以便毁掉函数调用
      • confirm:文件上传完毕后是否使用stat()方法,以便确认文件的大小

    注意: remotepath必须是文件路径+文件名+文件扩展名的完整形式,不能只指定文件夹的名字

    • 例子:
    localpath = '/home/access.log'remotepath = '/data/logs/access.log'sftp.put(localpath, remotepath)
  • get方法:从远程sftp服务端下载文件到本地 + get(self, remotepath, localpath, callback=None) + 参数说明: - remotepath:(str类型)远程文件路径 - localpath: (str类型)本地保存路径 - callback(function (int, int)):获取已经接收的字节数及宗的传输字节数, 以便毁掉函数调用 >注意: >localpath必须是文件路径+文件名+文件扩展名的完整形式,不能只指定文件夹的名字 + 例子: python localpath = '/home/access.log' remotepath = '/data/logs/access.log' sftp.put(localpath, remotepath)

  • mkdir:在远程服务器上创建文件夹

  • remove:删除SFTP服务端指定的目录

  • rename:重命名SFTP服务端的文件或目录

  • stat:获取SFTP服务端指定文件的信息

  • listdir:获取SFTP服务端指定的目录列表,以python list的形式返回。

    #! /usr/bin/python  import paramiko  __author__ = 'hgf'  username = "root"  password = "1qaz2wsx"  hostname = "10.109.33.163"  port = 22  paramiko.util.log_to_file('log.txt')  try:      t = paramiko.Transport((hostname, port))      t.connect(username=username, password=password)      sftp = paramiko.SFTPClient.from_transport(t)      sftp.put('/home/hgf/authorized_keys', '/root/aaaaa',)      sftp.get('/root/install.log', './server.log')      sftp.mkdir('/root/test', '700')      print(sftp.stat('/root/install.log'))      sftp.rmdir('/root/a')      print(sftp.listdir('/home'))      t.close()  except Exception, e:      print "Error!"      print(str(e))

Fabric

Fabricparamiko的基础上,做了更高一层的封装

安装

pip install fabric

全局属性的设置

与全局属性有关的是env对象。

常用API

例子1

查看本地与远程主机信息

例子2

动态获取远程目录列表

例子3

网关模式文件的上传

编写webserver

python处理命令行提示

python主要是使用optparse处理命令行的提示功能,并且响应命令行的输入参数。 例子:

MSG_USAGE = "program [-v] [-h]"parser = OptionParser(MSG_USAGE)parser.add_option("-v", "--version", action="store_true", dest="verbose", help="描述命令参数的用途")opts, args = parser.parse_args()if opts.verbose:  # 执行满足参数-v后的运行程序  print "输出系统的版本"  sys.exit()

python处理配置文件

python主要是使用configobj库来处理配置文件。 详细的使用请看《python配置文件configobj使用》

BaseHTTPServer.py源码分析

BaseHTTPServer.py源码分析主要是方便理解如何自己编写webserver。

SocketServer.py分析中可以知道其设计思想是将socket编程的监听循环和客户端处理划分成Server类和RequestHandler类,而BaseHTTPServer是基于SocketServer基础之上的,因此可以知道BaseHTTPServer就是分别扩展Server类和RequestHandler类。BaseHTTPServer实现了一个简单的HTTP Server,可以知道主要工作应该是扩展RequestHandler的功能,处理客户端的HTTP请求,具体包括HTTP协议解析,给客户端返回HTTP响应,日志记录等功能。

  1. HTTPServer

该类只是简单包装了SocketServer中的TCPServer

  1. BaseHTTPRequestHandler

类定义: class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):

扩展RequestHandler需要覆盖一个接口handler(),定义如下:

def handle(self):    """Handle multiple requests if necessary."""    self.close_connection = 1    self.handle_one_request()    while not self.close_connection:        self.handle_one_request()

主要处理的是HTTP是否保持连接的问题,如果保持连接就持续处理客户请求,否则就结束了。

handle_one_request()比较重要语句:

self.raw_requestline = self.rfile.readline(65537)self.parse_request()mname = 'do_' + self.commandif not hasattr(self, mname)    self.send_error(501, "Unsupported method (%r)" % self.command)    returnmethod = getattr(self, mname)method()self.wfile.flush() #actually send the response if not already done.
  • 读取第一行raw_requestline,一般格式应该是:COMMAND PATH VERSION\r\n
  • 解析请求,parse_request()主要的代码都在处理raw_requestline,最终得到self.command, self.path, self.request_version几个变量,然后就是利用mimetools.Message解析头部。
  • 后面几行代码意思是根据HTTP方法获取对应处理函数,其实就是根据GET或POST请求调用对应的do_GET()do_POST()方法,然后刷新输出。

下面还有几个的函数,功能都比较简单:

def send_error(self, code, message=None):def send_response(self, code, message=None):def send_header(self, keyword, value):def end_headers(self):def log_request(self, code='-', size='-'):def log_error(self, format, *args):def log_message(self, format, *args):

总结:可以看到,BaseHTTPRequestHandler主要实现了客户端HTTP请求解析,以及一些辅助功能,如日志记录、错误处理、发送响应代码等。 但是还没有实现如何执行HTTP请求,简单来说就是还需要实现诸如do_GET(),do_POST()等函数,具体执行对应的HTTP命令。

HTTP协议返状态码含义

  1. 1xx 状态码
表示临时响应并需要请求者继续执行操作的状态码。* `100(继续)` 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。* `101(切换协议)` 请求者已要求服务器切换协议,服务器已确认并准备切换。
  1. 2xx 状态码
表示成功处理了请求的状态码。* `200(成功)` 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。如果针对您的 robots.txt 文件显示此状态码,则表示 Googlebot 已成功检索到该文件。* `201(已创建)` 请求成功并且服务器创建了新的资源。* `202(已接受)` 服务器已接受请求,但尚未处理。* `203(非授权信息)` 服务器已成功处理了请求,但返回的信息可能来自另一来源。* `204(无内容)` 服务器成功处理了请求,但没有返回任何内容。* `205(重置内容)` 服务器成功处理了请求,但没有返回任何内容。与 204 响应不同,此响应要求请求者重置文档视图(例如,清除表单内容以输入新内容)。* `206(部分内容)` 服务器成功处理了部分 GET 请求。
  1. 3xx 状态码
要完成请求,需要进一步操作。通常,这些**状态码用来重定向**。建议您在每次请求中使用重定向不要超过 5 次。您可以使用网站管理员工具查看一下 Googlebot 在抓取重定向网页时是否遇到问题。诊断下的网络抓取页列出了由于重定向错误导致 Googlebot 无法抓取的网址。* `300(多种选择)` 针对请求,服务器可执行多种操作。服务器可根据请求者 (`user-agent`) 选择一项操作,或提供操作列表供请求者选择。* `301(永久移动)` 请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。您应使用此代码告诉 Googlebot 某个网页或网站已永久移动到新位置。* `302(临时移动)` 服务器目前从不同位置的网页响应请求,但申请人应当继续使用原有位置来响应以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似,会自动将请求者转到不同的位置,但不应使用此代码来告诉 Googlebot 页面或网站已经移动,因为 Googlebot 要继续抓取原来的位置并编制索引。* `303(查看其他位置)` 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。对于除 HEAD 之外的所有请求,服务器会自动转到其他位置。* `304(未修改)` 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。如果网页自请求者上次请求后再也没有更改过,您应当将服务器配置为返回此响应(称为 `If-Modified-Since HTTP` 标头)。由于服务器可以告诉 Googlebot 自从上次抓取后网页没有变更,因此可节省带宽和开销。* `305(使用代理)` 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应当使用代理。* `307(临时重定向)` 服务器目前从不同位置的网页响应请求,但请求者应当继续使用原有位置来响应以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似,会自动将请求者转到不同的位置,但您不应使用此代码来告诉 Googlebot 某个网页或网站已经移动,因为 Googlebot 会继续抓取原有位置并编制索引。
  1. 4xx 状态码
这些状态码表示请求可能出错,这妨碍了服务器的处理。* `400(错误请求)` 服务器不理解请求的语法。* `401(身份验证错误)` 此页要求授权。您可能不希望将此网页纳入索引。如果您的 Sitemap 中列出该网页,您可以将其删除。但如果您将其保留在您的 Sitemap 中,我们就不会抓取或索引该网页(尽管该网页将继续保持错误状态在此处列出)。如果我们将其作为搜索抓取的一部分抓取,您可以在我们的网站管理员信息中查阅其原因。* `403(禁止)` 服务器拒绝请求。如果您在 Googlebot 抓取您网站上的有效网页时看到此状态码,可能是您的服务器或主机拒绝 Googlebot 访问。* `404(未找到)` 服务器找不到请求的网页。例如,对于服务器上不存在的网页经常会返回此代码。* `405(方法禁用)` 禁用请求中指定的方法。* `406(不接受)` 无法使用请求的内容特性响应请求的网页。* `407(需要代理授权)` 此状态码与 401 类似,但指定请求者必须授权使用代理。如果服务器返回此响应,还表示请求者应当使用代理。* `408(请求超时)` 服务器等候请求时发生超时。* `409(冲突)` 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。服务器在响应与前一个请求相冲突的 PUT 请求时可能会返回此代码,以及两个请求的差异列表。* `410(已删除)` 请求的资源永久删除后,服务器返回此响应。该代码与 404(未找到)代码相似,但在资源以前存在而现在不存在的情况下,有时会用来替代 404 代码。如果资源已永久删除,您应当使用 301 指定资源的新位置。* `411(需要有效长度)` 服务器不接受不含有效内容长度标头字段的请求。* `412(未满足前提条件)` 服务器未满足请求者在请求中设置的其中一个前提条件。* `413(请求实体过大)` 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。* `414(请求的 URI 过长)` 请求的 URI(通常为网址)过长,服务器无法处理。* `415(不支持的媒体类型)` 请求的格式不受请求页面的支持。* `416(请求范围不符合要求)` 如果页面无法提供请求的范围,则服务器会返回此状态码。* `417(未满足期望值)` 服务器未满足"期望"请求标头字段的要求。
  1. 5xx 状态码
这些状态码表示服务器在处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。* `500(服务器内部错误)` 服务器遇到错误,无法完成请求。* `501(尚未实施)` 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时则会返回此代码。* `502(错误网关)` 服务器作为网关或代理,从上游服务器收到无效响应。* `503(服务不可用)` 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。* `504(网关超时)` 服务器作为网关或代理,但是没有及时从上游服务器收到请求。*  `505(HTTP 版本不受支持)` 服务器不支持请求中所用的 HTTP 协议版本。

转载于:https://my.oschina.net/hgfdoing/blog/514633

你可能感兴趣的文章
elixir mix 简介
查看>>
Android 调用浏览器和嵌入网页
查看>>
c#为了实现自己的线程池功能(一)
查看>>
C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)
查看>>
简单的取c#(flex)固定位数的随机数
查看>>
PHP全局变量
查看>>
ArcGIS API for Silverlight开发入门(4):用户与地理信息之间的桥梁--GraphicsLayer
查看>>
微渠道发展 BAE交通运输平台和java呼声,微信mysql数据库开发实例 --图文开发教程...
查看>>
LintCode: Count 1 in Binary
查看>>
【OC加强】NSDate的使用方法——日期时间在实际开发中比較有用
查看>>
SQL Server死锁总结(转载)
查看>>
iOS:步进UIStepper、滑动块UISlider、开关UISwitch的基本使用
查看>>
ubuntu安装deb,rpm安装包方法
查看>>
[Android Studio] Android Studio底边栏选项不见了,如何调出来
查看>>
Kali linux 2016.2(Rolling)里Metasploit连接(包括默认和自定义)的PostgreSQL数据库之后的切换到指定的工作空间...
查看>>
用jsmooth + inno生成exe并制作简单安装包
查看>>
关于spring-mvc.xml的mvc:resources元素浅析。
查看>>
Hadoop WordCount改进实现正确识别单词以及词频降序排序
查看>>
MVVM架构~knockoutjs实现简单的购物车
查看>>
ASP.NET图片上传方法总结
查看>>