野草博客 - Python
type: channel
link: http://www.cnweed.com/category/Python/
items: Linux MegaCli 根据盘符获取 RAID 位置与 盘位
items: Python结合MegaCLI对RAID列阵定时检测异常自动短信/电话通知
items: Centos7 Error Python.h No such file or directory
items: Python提取JSON数据的一个小例子
items: python 中json库的 对象转换
items: python按行读取文件 去掉换行符"\n"
items: python的for获取当前循环次数
items: Python 判断文件是否存在的三种方法
items: python中list的四种查找方法
items: python 字符串（str）和列表（list）的互相转换

Linux MegaCli 根据盘符获取 RAID 位置与 盘位
type: item
date: 2022-03-25T15:09:00+00:00
description: 我的CEPH OSD因为列阵卡不支持直通是基于RAID0的，最近ceph性能不足，排查过程iostat观察发现有一些盘r_await或w_await持续1000多，这就需要换盘了。ceph存储一份数据如果是默认3副本，那么就会3份副本写完才会完成写入，如果有1个osd延迟很高，就会影响整体写入速度。首先可以运行 ceph-volume lvm list 查看osd对应的盘符，如果是bcache，则需要再运行lsblk查看在哪个盘符下。然后查看是哪个盘符，以及盘位，进行更换重建。Python基于MegaCli获取raid卡状态的代码：https://raw.githubusercontent.com/eLvErDe/hwraid/master/wrapper-scripts/megaclisas-status这个大佬的python脚本可以快速帮忙定位，运行完后再执行下：lsscsi 查看盘符在系统中的编号就可以定位到盘了，记得MegaCli得先安装。代码贴上：#!/usr/bin/python # $Id: megaclisas-status,v 1.78 2018/10/01 03:52:57 root Exp root $ # # Written by Adam Cecile <gandalf@NOSPAM.le-vert.net> # Modified by Vincent S. Cojot <vincent@NOSPAM.cojot.name> # import os import re import sys import pdb import inspect import argparse os.system('lsscsi') if sys.platform == "win32": import ctypes def_megaclipath = "/opt/MegaRAID/MegaCli/MegaCli64" # Non-Nagios Mode defaults nagiosmode = False nagiosoutput = "" nagiosgoodarray = 0 nagiosbadarray = 0 nagiosgooddisk = 0 nagiosbaddisk = 0 # Sane defaults printarray = True printcontroller = True debugmode = False notempmode = False totaldrivenumber = 0 totalconfdrivenumber = 0 totalunconfdrivenumber = 0 # Hardcode a max of 16 HBA and 128 LDs for now. LDTable must be initialized to accept populating list of LD's into each ctlr's list. MaxNumHBA = 16 MaxNumLD = 128 LDTable = [[] * MaxNumHBA for i in range(MaxNumLD)] NestedLDTable = [[False for i in range(MaxNumLD)] for j in range(MaxNumHBA)] # Outputs is a 'dict' of all MegaCLI outputs so we can re-use them during loops.. Outputs = {} ConfDisks = {} NagiosBadDisks = {} NagiosGoodDisks = {} # We need root access to query if __name__ == "__main__": # deal with command line options parser = argparse.ArgumentParser() parser.add_argument("--nagios", help="enable nagios support", action="store_true") parser.add_argument("--debug", help="enable debugging output", action="store_true") parser.add_argument("--notemp", help="disable temperature reporting", action="store_true") args = parser.parse_args() nagiosmode = a…

Python结合MegaCLI对RAID列阵定时检测异常自动短信/电话通知
type: item
date: 2020-06-10T08:27:00+00:00
description: 公司有台10个盘组的RAID10的服务器列阵挂了，坏了3个盘，超过了RAID10的容错，已经无法通过列阵恢复数据了。同时挂3个是很小几率的，所以也有一定可能刚开始挂了1-2个不知道，直到第3个挂了down机了才发现。因为机器很多，人工每天检查一次会比较耗时，每周检查也许又会太长。所以写了个py小脚本，可以定时1小时检查次，出现故障可以立即通知到技术立即去进一步检查、换盘，避免悲剧发生。1、安装MegaCLI# wget https://raw.githubusercontent.com/crazy-zhangcong/tools/master/MegaCli8.07.10.tar.gz && tar -zxf MegaCli8.07.10.tar.gz && cd MegaCli8.07.10/Linux/ && rpm -ivh Lib_Utils-1.00-09.noarch.rpm MegaCli-8.02.21-1.noarch.rpm && ln -s /opt/MegaRAID/MegaCli/MegaCli64 /usr/local/bin/MegaCli && MegaCli -v 出现如下信息即正常完成安装MegaCLI SAS RAID Management Tool Ver 8.02.21 Oct 21, 2011(c)Copyright 2011, LSI Corporation, All Rights Reserved. Exit Code:0x002、Python脚本# -*- coding: utf-8 -*- #!/usr/bin/python import os import requests node = '宽带型VPS宿主服务器1' #填写节点名称 error = 0 def get_status(value): status = value.split(": ") return status[1] def send_warning(): global node # 语音通知 基于 https://www.mysubmail.com 语音通知接口 voice_url = 'https://api.mysubmail.com/voice/send.json' voice_params = { 'appid': '', 'to': '13200000000', 'content': '紧急事态：'+node+'硬盘状态异常，请立即检查', 'signature': '' #填写应用密匙 } voice_res = requests.post(voice_url, data=voice_params) # print voice_res.text # 短信通知 基于 https://www.mysubmail.com 短信接口 message_url = 'https://api.mysubmail.com/message/send.json' message_params = { 'appid': '', 'to': '13200000000', 'content': '【xx科技】紧急事态：'+node+'硬盘状态异常，请立即检查', 'signature': '' #填写应用密匙 } message_res = requests.post(message_url, data=message_params) # print message_res.text # 检查RAID状态 # raidinfos = open('raid.log','r') # for raidinfo in raidinfos.readlines(): raidinfos = os.popen('/opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -Lall -aALL -NoLOG').readlines() for raidinfo in raidinfos: raidinfo = raidinfo.strip('\n') if "State" in raidinfo: status = get_status(raidinfo) if status != 'Optimal': error = 1 print(raidinfo+'\n') # 检查所有磁盘状态 # pdlist = open('raid_pdlist.log','r') # for line in pdlist.readlines(): pdlist = os.popen('/opt/MegaRAID/MegaCli/MegaCli64 -PDList -aALL -NoLOG').readlines() for lin…

Centos7 Error Python.h No such file or directory
type: item
date: 2020-02-15T21:01:35+00:00
description: 系统没有安装python-devel包导致yum install python-devel.x86_64

Python提取JSON数据的一个小例子
type: item
date: 2018-04-20T07:22:20+00:00
description: import json json_data = """{ "favourite":{ "bkmrk":{ "id1490843709594066":{ "guid":"904eff52277f403b89f6410fe2758646.11", "lcate":"1" }, "id1490843712805183":{ "guid":"58457f60eca64025bc43a978f9c98345.16", "lcate":"2" }, "id149084371467327":{ "guid":"a0f907f9dc8b40f689b083f3eba7228b.16", "lcate":"3" }, "id1490843716295393":{ "guid":"eb75d929455e468bb712e7bc2025d11a.16", "lcate":"4" } } } }""" data = json.loads(json_data) for v in data['favourite']['bkmrk'].values(): print("%s;%s" % (v['lcate'], v['guid']))

python 中json库的 对象转换
type: item
date: 2018-04-20T07:20:00+00:00
description: 接收一个post的json字符串:s={"username":"admin","password":"password","tenantid":""} 使用python自带的json库import json >>> a=json.loads(s) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/json/__init__.py", line 326, in loads return _default_decoder.decode(s) File "/usr/lib/python2.7/json/decoder.py", line 366, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) TypeError: expected string or buffer >>> 出错！百思不得其解。经过调试，最终发现，python中默认使用单引号表示字符串"'"所以当，用字符串符值以后，python会把双引号转换为单引号>>> s={"username":"admin","password":"password","tenantid":""} >>> print s {'username': 'admin', 'password': 'password', 'tenantid': ''} 而json是不支持单引号的。可以用下面的方法转换json_string=json.dumps(s) python_obj=json.loads(json_string) https://www.cnblogs.com/biangbiang/archive/2013/01/21/2869581.html

python按行读取文件 去掉换行符"\n"
type: item
date: 2018-04-20T07:18:00+00:00
description: eg:#! /usr/bin/python import sys import string import os base_dir="/home/qinjianwang/mtr_dir/2012_09_12/tw" as_uniq_info=base_dir + "/as_uniq_info" get_line_num="wc -l " + as_uniq_info + " | awk '{print $1}'" ###get the lines of "as_uniq_info" line_num = os.popen(get_line_num).read().strip('\n') global VEXNUM VEXNUM = string.atoi(line_num) python 字符串连接base_dir="/home/qinjianwang/mtr_dir/2012_09_12/tw" as_uniq_info=base_dir + "/as_uniq_info" 有：as_uniq_info="/home/qinjianwang/mtr_dir/2012_09_12/tw/as_uniq_info"需要注意以下这句：get_line_num="wc -l " + as_uniq_info + " | awk '{print $1}'" ###get the lines of "as_uniq_info" 注意1：拼接shell命令时，需要引用python中的变量as_uniq_info，as_uniq_info单独拿出来，再拼接其它命令，不要写成下面这样：get_line_num="wc -l as_uniq_info | awk '{print $1}'" 这样写会造成shell无法正确替换python中的变量as_uniq_info。注意2：拼接shell命令时，要注意引号中命令间的留空，如以下"wc -l " 和 " | awk '{print $1}'" 引号"wc -l “中的 -l 后面就需要留空，要注意。python 调用 shellget_line_num="wc -l as_uniq_info | awk '{print $1}'" ###get the lines of "as_uniq_info"line_num = os.popen(get_line_num).read().strip('\n')get_line_num 作为shell执行的命令，会取得文件as_uniq_info文件的行数os.popen(get_line_num)：执行shellget_line_num = os.popen(get_line_num).read():调用read，赋值给get_line_num，此时get_line_num中含有一个换行符（"\n"）。os.popen(get_line_num).read().strip('\n')：去掉换行符shell 引用python变量line_num = os.popen(get_line_num) 引用了python中的get_line_num变量。python引用shell中值line_num = os.popen(get_line_num).read() 执行完shell后，通过read()函数，赋值给python中的变量line_numpython 去掉换行符"\n" line_num = os.popen(get_line_num).read().strip('\n') 通过strip()函数，去掉换行符"\n" python按行读取文件 去掉换行符"\n"for line in file.readlines(): line=line.strip('\n') Python 字符转实型b="123.678" >>> string.atof(b) 123.678 Python 字符转整型VEXNUM = string.atoi(line_num)

python的for获取当前循环次数
type: item
date: 2018-04-20T07:05:12+00:00
description: enumerate是python 2.3中新增的内置函数，它的英文说明为：enumerate( iterable)Return an enumerate object. iterable must be a sequence, an iterator,or some other object which supports iteration. The next() method ofthe iterator returned by enumerate() returns a tuple containing acount (from zero) and the corresponding value obtained from iteratingover iterable. enumerate() is useful for obtaining an indexed series:(0, seq[0]), (1, seq[1]), (2, seq[2]), .... New in version 2.3.它特别适合用于一个for循环时，当我们同时需要计数和元素时可以使用这个函数。举个简单的例子，有一个字符串数组，需要一行一行打印出来，同时每行前面加上计数，从1开始。>> s = ['abc', 'This is a test', 'Hello, Python'] >> for i, line in enumerate(s): >> print i+1, line

Python 判断文件是否存在的三种方法
type: item
date: 2018-04-11T10:24:00+00:00
description: 通常在读写文件之前，需要判断文件或目录是否存在，不然某些处理方法可能会使程序出错。所以最好在做任何操作之前，先判断文件是否存在。这里将介绍三种判断文件或文件夹是否存在的方法，分别使用os模块、Try语句、pathlib模块。1.使用os模块os模块中的os.path.exists()方法用于检验文件是否存在。判断文件是否存在import os #如果存在返回True >>>os.path.exists('test_file.txt') >>>True #如果不存在返回False >>>os.path.exists('no_exist_file.txt') >>>False 判断文件夹是否存在import os >>>os.path.exists('test_dir') >>>True >>>os.path.exists('no_exist_dir') >>>False 可以看出用os.path.exists()方法，判断文件和文件夹是一样。其实这种方法还是有个问题，假设你想检查文件“test_data”是否存在，但是当前路径下有个叫“test_data”的文件夹，这样就可能出现误判。为了避免这样的情况，可以这样:只检查文件>>>import os >>>os.path.isfile("test-data") 通过这个方法，如果文件”test-data”不存在将返回False，反之返回True。即是文件存在，你可能还需要判断文件是否可进行读写操作。**判断文件是否可做读写操作使用os.access()方法判断文件是否可进行读写操作。**语法：os.access(path, mode) path为文件路径，mode为操作模式，有这么几种:os.F_OK: 检查文件是否存在;os.R_OK: 检查文件是否可读;os.W_OK: 检查文件是否可以写入;os.X_OK: 检查文件是否可以执行该方法通过判断文件路径是否存在和各种访问模式的权限返回True或者False。>>>import os >>>if os.access("/file/path/foo.txt", os.F_OK): >>> print "Given file path is exist." >>>if os.access("/file/path/foo.txt", os.R_OK): >>> print "File is accessible to read" >>>if os.access("/file/path/foo.txt", os.W_OK): >>> print "File is accessible to write" >>>if os.access("/file/path/foo.txt", os.X_OK): >>> print "File is accessible to execute" 2.使用Try语句语法：open(<file/path>) 如果你open的文件不存在，程序会抛出错误，使用try语句来捕获这个错误。 程序无法访问文件，可能有很多原因：如果你open的文件不存在，将抛出一个FileNotFoundError的异常;文件存在，但是没有权限访问，会抛出一个PersmissionError的异常。所以可以使用下面的代码来判断文件是否存在:try: f =open() f.close() except FileNotFoundError: print "File is not found." except PersmissionError: print "You don't have permission to access this file." 其实没有必要去这么细致的处理每个异常，上面的这两个异常都是IOError的子类。所以可以将程序简化一下:try: f =open() f.close() except IOError: print "File is not accessible." 使用try语句进行判断，处理所有异常非常简单和优雅的。而且相比其他不需要引入其他外部模块。3. 使用pathlib模块 pathlib模块在Python3版本中是内建模块，但是在Python2中是需要单独安装三方模块。使用pathlib需要先使用文件路径来创建path对象。此路径可以是文件名或目录路径。检查路径是否存在path = pathlib.Path("path/file") path.exist() 检查路径是否是文件path = pathlib.Path("path/file") path.is_file() 判断文件是否为空：#!/usr/bin/env python #coding:utf-8 #date:2018-04-03 …

python中list的四种查找方法
type: item
date: 2018-04-11T10:17:00+00:00
description: Python中是有查找功能的，四种方式：in、not in、count、index，前两种方法是保留字，后两种方式是列表的方法。下面以a_list = ['a','b','c','hello']，为例作介绍：1、 判断值是否在列表中，in操作符# 判断a是否在列表中，并返回True或False 'a' in a_list 2、 判断值是否不在列表，not in操作符：# 判断a是否不在列表中，并返回True或False 'a' not in a_list 3、 统计指定值在列表中出现的次数，count方法# 返回a在列表中的出现的次数 a_list.count('a') 5、 查看指定值在列表中的位置，index方法# 返回a在列表中每一次出现的位置，默认搜索整个列表 a_list.index('a') # 返回a在指定切片内的第一次出现位置 a_list.index('a',0,3)

python 字符串（str）和列表（list）的互相转换
type: item
date: 2018-04-11T10:10:33+00:00
description: 1.str >>>liststr1 = "12345" list1 = list(str1) print list1 str2 = "123 sjhid dhi" list2 = str2.split() #or list2 = str2.split(" ") print list2 str3 = "www.google.com" list3 = str3.split(".") print list3 输出为:['1', '2', '3', '4', '5'] ['123', 'sjhid', 'dhi'] ['www', 'google', 'com'] 3.list >>>strstr4 = "".join(list3) print str4 str5 = ".".join(list3) print str5 str6 = " ".join(list3) print str6 输出为： wwwgooglecom www.google.com www google com 参考：https://blog.csdn.net/roytao2/article/details/53433373