分类目录归档:Python

python异常捕获

在Python中处理异常使用的是try-except代码块,try-except代码块放入让python执行的操作,同时告诉python程序如果发生了异常该怎么办,try-except这个功能其实很多入门书籍中都放到了高级篇幅里,在入门的时候一般不会讲这个使用,尤其是作为运维人员,如果你经常写shell,转到python后估计也很少使用这个功能,这功能我觉得说明了shell和python的一个重要区别,因为python是一门真正的编程语言,像其它的编程语言php,java等都会提供异常捕获功能,用这些程序写出的代码是要健壮性的,如果你阅读一些其他人写的程序代码,尤其是一些socket编程方面的代码,很多都是try…except…,有的还except好多个,来判断各种各样的情况,既然这个功能这么有用,我们就来尽快了解下看如何使用的吧。

第一我们先看看它的语法,语法很简单,就是在try-except中放入你想要执行的代码块,例如:、

这是最简单的一种情况,如果情况复杂可以使用多个except句子,例如:

try-except还有更高级的用法,加入else,finally等,今天我们不展开说了有兴趣的可以自己深入研究下。

接下来我们来看一个简单例子,读写文件我们经常的操作,一个常见的问题就是找不到文件,或者文件名称,路径不正确,对这种情况,你就可以采用try-except代码块直观的方式来处理了:

我们再看一个多except的例子,2个数字相减:

以上二个例子就是最简单的try-except的用法了,如果想要保证脚本的健壮性,后续可多用try-except代码块吧,这会让你的代码看起来更专业。

 

 

python脚本pdb调试工具使用

pdb是linux的的python调试工具,它功能比较齐全,使用起来也很方便, 按一边运维工程师的发展来说,一般最早接触的是shell编程, 所以大多是在shell的基础上开始学习Python的,如果是刚 从shell脚本转到写python脚本的小伙伴可能会有点不太适应,比如说调试,大家都知道写脚本是有一个调试过程的除非你的脚本里只有一行, 那既然都有调试过程,那shell下调试就很方便,shell运行时我们可以直接 sh -x  myscript.sh ,就可以看到整个脚本运行的过程,或者在某些关键地方加入echo ,打印出变量,调试方法简单直接, 所以在写Python脚本时我们继承了写shell脚本的调试习惯,我们会在程序中加入print 来调试关键变量,这也是现在大家通用的方法,但有时候就行不通,如果一个脚本写的很长,有涉及到某些逻辑在里面,用print就显得无力了,如果你不掌握调试方法,那完成一个稍微复杂的脚本是相当痛苦的,所以掌握调试工具是写出复杂程序的必备技能,那就引出了今天我们要说的pdb调试工具。

开始前我们先了解下pdb的常用命令:

1、step:单步调试,执行下一行代码,但是有函数调用会进入函数内部。

2、next:执行下一行代码,如果当前语句有函数调用,则不会进入函数体中

3、break:设置程序断点,

4、continue:继续执行程序,直到下一个断点

5、list:显示第几行,例如:list 50

6、print:这个就是打印想看的参数

7、quit:退出

我们拿一个例子看如果具体应用:

比如我调试我之前的脚本:parser_nginx_log.py

我用最简单的方式在终端开始运行:

python -m pdb  parser_nginx_log.py

截图如下:

pdb

 

 

 

调用zabbix API获取主机

zabbix 作为企业级的系统和网络监控方案,对于中小型公司来说基本可以很好的满足对机器的监控需求,因为其部署方便,操作简单深受现在各个互联网公司喜爱,所以现在基本的互联网公司监控用zabbix的非常多,当你安装好zabbix服务端 后,如果启动自动注册功能,在所有客户机安装后会自动在zabbix平台上被监控到,但这里有个问题,如果你机器数量非常少,如果还能数的过来那基本没什么问题,但如果你机器上千台了,这个时候那些机器被监控中,那些没被监控,查起来就没那么方便了,所以日常运维中经常发现的问题就是某台机器故障了但没报警,经查发现这台机器zabbix客户端因为某种原因导致没有被服务端监控到,像这种问题怎么办呢?其实最简单的方案就是从zabbix里获取所有被监控的服务器列表,然后跟运维资产数据库去比对,如果数量一致,那说明监控没漏机器,如果比对不上,就把对不上的IP发出来再报个警就可以了,整体逻辑就是这样,我们今天用zabbix api获取被监控的所有机器列表,代码如下:

 

脚本一共分二部分,第一部分是用户登录,登录后然后获取主机列表,最后写到一个文件里去,所以脚本运行的结果是生成一个所有被监控的IP列表,通过这个列表你就可以去跟你的资产库信息去对比了,还有这个脚本用的requests,所以看起来要清爽很多,代码比较简单,就是二个post就不做太多解释了,今天就到这里,喜欢的小伙伴可以在此基础上修改成合适自己业务的脚本。

你应该学会的python列表去重

列表去重是写Python脚本时常遇问题,因为不管源数据来自哪里,当我们转换成列表的方式时,有可能预期的结果不是我们最终的结果,最常见的就是列表中元素有重复,这时候第一件事我们就要做去重处理,我们先来个最简单的方式,用python内置的数据类型set来实现。

假设我们的列表数据是这样的:

因为集合的元素是不能重复的,所以将列表转换成集合时,会自动去掉重复的元素,这就是基本原理,代码如下:

这种方式缺点是再转换成列表时无法保存之前的列表顺序,如果没这个要求,这种方式是最简答的, 也许有的小伙伴觉得好简单呀,这没什么技术含量吗,没错,所以一般面试题里让你列表去重一般会这么写:

请写出列表去重的方法(不能用set)

人家写明不能用set了,所以呢,这招有时候还不能用,那当然也难不倒我们,我们还有其他方法。

我们都知道列表可以遍历,能遍历问题也就简单了,我们再定义空列表,然后遍历有数据的列表,再遍历时加一个判断,如果在空列表里没有,就加进去,如果有了就丢掉,代码如下:

 

大家觉得这种方式是不是还可以,但这种方式对付一般的小列表是没问题的,但如果遇到一个超级大列表,也会力不从心,因为在the_list列表变的非常大,在判断时候会影响效率,因为列表是按索引顺序去查找的,当数据量很大时会变慢。

也许你要问了,那我遇到大的列表咋办? 有更牛掰点的方法吗?当然有,让我们继续,既然在判断时用列表会影响效率,那我们就转换一个思路,我们用集合,那你可能要问了,那集合就快了?没错,因为set使用的hash函数查找值,虽然set无序,但位置是固定的,只需一次就可以查到特定元素是否存在,网上有人做了列表和set的元素查找对比,相同的数据条件下,用list耗时16分钟,用set耗时是52秒,这一对比看出效果了吧,别的不多说了,贴代码:

列表去重的方法就介绍到这里,欢迎转发~

python按任意键继续程序

在windows下写bat的时候,通过pause命令,可以暂停程序运行,例如经常见的程序会在终端提示”按任意键继续……”,用户在终端回车后程序可以接着运行,这个功能有多大用途今天暂且不说,但我觉得应该有很多人也想在python下实现这个功能,这样当自己写的python程序运行时, 突然给出这么一个提示,然后自己再来个帅气的回车,我觉得肯定给人一种非常专业的感觉,最起码自己肯定被自己迷倒了,所以今天我们就学习下这段代码,这里定义了一个函数,所以你可以嵌入到你的程序中,在任何你希望调用的地方调用它即可,使用非常的方便,代码如下:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import os

import sys

import termios

def press_any_key_exit(msg):

# 获取标准输入的描述符

fd = sys.stdin.fileno()

# 获取标准输入(终端)的设置

old_ttyinfo = termios.tcgetattr(fd)

# 配置终端

new_ttyinfo = old_ttyinfo[:]

# 使用非规范模式(索引3是c_lflag 也就是本地模式)

new_ttyinfo[3] &= ~termios.ICANON

# 关闭回显(输入不会被显示)

new_ttyinfo[3] &= ~termios.ECHO

# 输出信息

sys.stdout.write(msg)

sys.stdout.flush()

# 使设置生效

termios.tcsetattr(fd, termios.TCSANOW, new_ttyinfo)

# 从终端读取

os.read(fd, 7)

# 还原终端设置

termios.tcsetattr(fd, termios.TCSANOW, old_ttyinfo)

if __name__ == “__main__”:

press_any_key_exit(“按任意键继续…”)

print ‘\n’

代码不多解释,看注释,这里要说一下termios模块,这个模块提供了一个接口可以控制tty终端的Io,它所有函数第一个参数需要一个文件描述符,可以是整型的文件描述符,也可以是个文件对象,因为它可以控制在终端的显示设置,常用场景就是用户在终端输入密码时不要显示出来,就跟我们用root登陆系统时系统给出输入密码提示符一样, 代码实现如下:

def getpass(prompt=”Password: “):

import termios, sys

fd = sys.stdin.fileno()

old = termios.tcgetattr(fd)

new = termios.tcgetattr(fd)

new[3] = new[3] & ~termios.ECHO

try:

termios.tcsetattr(fd, termios.TCSADRAIN, new)

passwd = raw_input(prompt)

finally:

termios.tcsetattr(fd, termios.TCSADRAIN, old)

return passwd

passwd = getpass()

print passwd

这个脚本运行会提示你输入密码,输入后会打印出刚输入的密码,给这个2个例子也是说明termios的简单用法,大家可以自己运行程序去体会下。