python 多线程理解(二)

之前讲了多线程的一篇博客,感觉讲的意犹未尽,其实,多线程非常有意思。因为我们在使用电脑的过程中无时无刻都在多进程和多线程。我们可以接着之前的例子继续讲。请先看我的上一篇博客。
从上面例子中发现线程的创建是颇为麻烦的,每创建一个线程都需要创建一个tx(t1、t2、…),如果创建的线程多时候这样极其不方便。下面对通过例子进行继续改进:

player.py
复制代码

#coding=utf-8
from time import sleep, ctime
import threading

def muisc(func):
for i in range(2):
print ‘Start playing: %s! %s’ %(func,ctime())
sleep(2)

def move(func):
for i in range(2):
print ‘Start playing: %s! %s’ %(func,ctime())
sleep(5)

def player(name):
r = name.split(‘.’)[1]
if r == ‘mp3’:
muisc(name)
else:
if r == ‘mp4’:
move(name)
else:
print ‘error: The format is not recognized!’

list = [‘爱情买卖.mp3′,’阿凡达.mp4’]

threads = []
files = range(len(list))

#创建线程
for i in files:
t = threading.Thread(target=player,args=(list[i],))
threads.append(t)

if __name__ == ‘__main__’:
#启动线程
for i in files:
threads[i].start()
 for i in files:
   threads[i].join()

#主线程
print ‘end:%s’ %ctime()

复制代码

  有趣的是我们又创建了一个player()函数,这个函数用于判断播放文件的类型。如果是mp3格式的,我们将调用music()函数,如果是mp4格式的我们调用move()函数。哪果两种格式都不是那么只能告诉用户你所提供有文件我播放不了。

  然后,我们创建了一个list的文件列表,注意为文件加上后缀名。然后我们用len(list) 来计算list列表有多少个文件,这是为了帮助我们确定循环次数。

  接着我们通过一个for循环,把list中的文件添加到线程中数组threads[]中。接着启动threads[]线程组,最后打印结束时间。

split()可以将一个字符串拆分成两部分,然后取其中的一部分。

复制代码

>>> x = ‘testing.py’
>>> s = x.split(‘.’)[1]
>>> if s==’py’:
print s

py

复制代码

运行结果:

Start playing: 爱情买卖.mp3! Mon Apr 21 12:48:40 2014
Start playing: 阿凡达.mp4! Mon Apr 21 12:48:40 2014
Start playing: 爱情买卖.mp3! Mon Apr 21 12:48:42 2014
Start playing: 阿凡达.mp4! Mon Apr 21 12:48:45 2014
end:Mon Apr 21 12:48:50 2014

现在向list数组中添加一个文件,程序运行时会自动为其创建一个线程。

继续改进例子:

  通过上面的程序,我们发现player()用于判断文件扩展名,然后调用music()和move() ,其实,music()和move()完整工作是相同的,我们为什么不做一台超级播放器呢,不管什么文件都可以播放。经过改造,我的超级播放器诞生了。

super_player.py

复制代码

#coding=utf-8
from time import sleep, ctime
import threading

def super_player(file,time):
for i in range(2):
print ‘Start playing: %s! %s’ %(file,ctime())
sleep(time)

#播放的文件与播放时长
list = {‘爱情买卖.mp3′:3,’阿凡达.mp4′:5,’我和你.mp3’:4}

threads = []
files = range(len(list))

#创建线程
for file,time in list.items():
t = threading.Thread(target=super_player,args=(file,time))
threads.append(t)

if __name__ == ‘__main__’:
#启动线程
for i in files:
threads[i].start()
  for i in files:
   threads[i].join()

#主线程
print ‘end:%s’ %ctime()

复制代码

  首先创建字典list ,用于定义要播放的文件及时长(秒),通过字典的items()方法来循环的取file和time,取到的这两个值用于创建线程。

  接着创建super_player()函数,用于接收file和time,用于确定要播放的文件及时长。

  最后是线程启动运行。运行结果:
复制代码

Start playing: 爱情买卖.mp3! Fri Apr 25 09:45:09 2014
Start playing: 我和你.mp3! Fri Apr 25 09:45:09 2014
Start playing: 阿凡达.mp4! Fri Apr 25 09:45:09 2014
Start playing: 爱情买卖.mp3! Fri Apr 25 09:45:12 2014
Start playing: 我和你.mp3! Fri Apr 25 09:45:13 2014
Start playing: 阿凡达.mp4! Fri Apr 25 09:45:14 2014
end:Fri Apr 25 09:45:19 2014

复制代码

创建自己的多线程类

复制代码

#coding=utf-8
import threading
from time import sleep, ctime

class MyThread(threading.Thread):

def __init__(self,func,args,name=”):
threading.Thread.__init__(self)
self.name=name
self.func=func
self.args=args

def run(self):
apply(self.func,self.args)

def super_play(file,time):
for i in range(2):
print ‘Start playing: %s! %s’ %(file,ctime())
sleep(time)

list = {‘爱情买卖.mp3′:3,’阿凡达.mp4’:5}

#创建线程
threads = []
files = range(len(list))

for k,v in list.items():
t = MyThread(super_play,(k,v),super_play.__name__)
threads.append(t)

if __name__ == ‘__main__’:
#启动线程
for i in files:
threads[i].start()
  for i in files:
   threads[i].join()

#主线程
print ‘end:%s’ %ctime()

复制代码

MyThread(threading.Thread)

创建MyThread类,用于继承threading.Thread类。

__init__()

使用类的初始化方法对func、args、name等参数进行初始化。

apply()

  apply(func [, args [, kwargs ]]) 函数用于当函数参数已经存在于一个元组或字典中时,间接地调用函数。args是一个包含将要提供给函数的按位置传递的参数的元组。如果省略了args,任何参数都不会被传递,kwargs是一个包含关键字参数的字典。

apply() 用法:

复制代码

#不带参数的方法
>>> def say():
print ‘say in’

>>> apply(say)
say in

#函数只带元组的参数
>>> def say(a,b):
print a,b

>>> apply(say,(‘hello’,’虫师’))
hello 虫师

#函数带关键字参数
>>> def say(a=1,b=2):
print a,b

>>> def haha(**kw):
apply(say,(),kw)

>>> haha(a=’a’,b=’b’)
a b

复制代码

MyThread(super_play,(k,v),super_play.__name__)

由于MyThread类继承threading.Thread类,所以,我们可以使用MyThread类来创建线程。

运行结果:

Start playing: 爱情买卖.mp3! Fri Apr 25 10:36:19 2014
Start playing: 阿凡达.mp4! Fri Apr 25 10:36:19 2014
Start playing: 爱情买卖.mp3! Fri Apr 25 10:36:22 2014
Start playing: 阿凡达.mp4! Fri Apr 25 10:36:24 2014
all end: Fri Apr 25 10:36:29 2014

python 多线程理解(一)

单线程

  在好些年前的MS-DOS时代,操作系统处理问题都是单任务的,我想做听音乐和看电影两件事儿,那么一定要先排一下顺序。

(好吧!我们不纠结在DOS时代是否有听音乐和看影的应用。^_^)
复制代码

from time import ctime,sleep

def music():
for i in range(2):
print “I was listening to music. %s” %ctime()
sleep(1)

def move():
for i in range(2):
print “I was at the movies! %s” %ctime()
sleep(5)

if __name__ == ‘__main__’:
music()
move()
print “all over %s” %ctime()

复制代码

  我们先听了一首音乐,通过for循环来控制音乐的播放了两次,每首音乐播放需要1秒钟,sleep()来控制音乐播放的时长。接着我们又看了一场电影,

每一场电影需要5秒钟,因为太好看了,所以我也通过for循环看两遍。在整个休闲娱乐活动结束后,我通过

print “all over %s” %ctime()

看了一下当前时间,差不多该睡觉了。

运行结果:
复制代码

>>=========================== RESTART ================================
>>>
I was listening to music. Thu Apr 17 10:47:08 2014
I was listening to music. Thu Apr 17 10:47:09 2014
I was at the movies! Thu Apr 17 10:47:10 2014
I was at the movies! Thu Apr 17 10:47:15 2014
all over Thu Apr 17 10:47:20 2014

复制代码

  

  其实,music()和move()更应该被看作是音乐和视频播放器,至于要播放什么歌曲和视频应该由我们使用时决定。所以,我们对上面代码做了改造:
复制代码

#coding=utf-8
import threading
from time import ctime,sleep

def music(func):
for i in range(2):
print “I was listening to %s. %s” %(func,ctime())
sleep(1)

def move(func):
for i in range(2):
print “I was at the %s! %s” %(func,ctime())
sleep(5)

if __name__ == ‘__main__’:
music(u’爱情买卖’)
move(u’阿凡达’)

print “all over %s” %ctime()

复制代码

  对music()和move()进行了传参处理。体验中国经典歌曲和欧美大片文化。

运行结果:
复制代码

>>> ======================== RESTART ================================
>>>
I was listening to 爱情买卖. Thu Apr 17 11:48:59 2014
I was listening to 爱情买卖. Thu Apr 17 11:49:00 2014
I was at the 阿凡达! Thu Apr 17 11:49:01 2014
I was at the 阿凡达! Thu Apr 17 11:49:06 2014
all over Thu Apr 17 11:49:11 2014

复制代码

多线程

  科技在发展,时代在进步,我们的CPU也越来越快,CPU抱怨,P大点事儿占了我一定的时间,其实我同时干多个活都没问题的;于是,操作系统就进入了多任务时代。我们听着音乐吃着火锅的不在是梦想。

  python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补,为了不浪费你和时间,所以我们直接学习threading 就可以了。

继续对上面的例子进行改造,引入threadring来同时播放音乐和视频:
复制代码

#coding=utf-8
import threading
from time import ctime,sleep

def music(func):
for i in range(2):
print “I was listening to %s. %s” %(func,ctime())
sleep(1)

def move(func):
for i in range(2):
print “I was at the %s! %s” %(func,ctime())
sleep(5)

threads = []
t1 = threading.Thread(target=music,args=(u’爱情买卖’,))
threads.append(t1)
t2 = threading.Thread(target=move,args=(u’阿凡达’,))
threads.append(t2)

if __name__ == ‘__main__’:
for t in threads:
t.setDaemon(True)
t.start()

print “all over %s” %ctime()

复制代码

import threading

首先导入threading 模块,这是使用多线程的前提。

threads = []

t1 = threading.Thread(target=music,args=(u’爱情买卖’,))

threads.append(t1)

  创建了threads数组,创建线程t1,使用threading.Thread()方法,在这个方法中调用music方法target=music,args方法对music进行传参。 把创建好的线程t1装到threads数组中。

  接着以同样的方式创建线程t2,并把t2也装到threads数组。

for t in threads:

  t.setDaemon(True)

  t.start()

最后通过for循环遍历数组。(数组被装载了t1和t2两个线程)

setDaemon()

  setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。子线程启动后,父线程也继续执行下去,当父线程执行完最后一条语句print “all over %s” %ctime()后,没有等待子线程,直接就退出了,同时子线程也一同结束。

start()

开始线程活动。

运行结果:

>>> ========================= RESTART ================================
>>>
I was listening to 爱情买卖. Thu Apr 17 12:51:45 2014 I was at the 阿凡达! Thu Apr 17 12:51:45 2014 all over Thu Apr 17 12:51:45 2014

  从执行结果来看,子线程(muisc 、move )和主线程(print “all over %s” %ctime())都是同一时间启动,但由于主线程执行完结束,所以导致子线程也终止。

继续调整程序:
复制代码


if __name__ == ‘__main__’:
for t in threads:
t.setDaemon(True)
t.start()

t.join()

print “all over %s” %ctime()

复制代码

  我们只对上面的程序加了个join()方法,用于等待线程终止。join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

  注意: join()方法的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。

运行结果:
复制代码

>>> ========================= RESTART ================================
>>>
I was listening to 爱情买卖. Thu Apr 17 13:04:11 2014 I was at the 阿凡达! Thu Apr 17 13:04:11 2014

I was listening to 爱情买卖. Thu Apr 17 13:04:12 2014
I was at the 阿凡达! Thu Apr 17 13:04:16 2014
all over Thu Apr 17 13:04:21 2014

复制代码

  从执行结果可看到,music 和move 是同时启动的。

  开始时间4分11秒,直到调用主进程为4分22秒,总耗时为10秒。从单线程时减少了2秒,我们可以把music的sleep()的时间调整为4秒。
复制代码


def music(func):
for i in range(2):
print “I was listening to %s. %s” %(func,ctime())
sleep(4)

复制代码

执行结果:
复制代码

>>> ====================== RESTART ================================
>>>
I was listening to 爱情买卖. Thu Apr 17 13:11:27 2014I was at the 阿凡达! Thu Apr 17 13:11:27 2014

I was listening to 爱情买卖. Thu Apr 17 13:11:31 2014
I was at the 阿凡达! Thu Apr 17 13:11:32 2014
all over Thu Apr 17 13:11:37 2014

复制代码

  子线程启动11分27秒,主线程运行11分37秒。

  虽然music每首歌曲从1秒延长到了4 ,但通多程线的方式运行脚本,总的时间没变化。

本文从感性上让你快速理解python多线程的使用,更详细的使用请参考其它文档或资料。

Python 调用jenkins接口自动发布脚本

#!/opt/venv/bin/python
# coding: utf-8
# author: —

import jenkins
import sys
import threading
import time

url_dict={‘qa’:’http://xx.xx.xx.xx/jenkins/’,
‘jq’:’http://xx.xx.xx.xx/jenkins’,
‘prd’:’http://xx.xx.xx.xx/jenkins’}

username_dict={‘qa’:’admin’,’jq’:’admin’,’prd’:’admin’}

token_dict={‘qa’:’009753b3087cdc9be9c76c9a40f0f99a’,
‘jq’:’5a2ded6a567f5b76d23e8e0c241fc478′,
‘prd’:’5a2ded6a567f5b76d23e8e0c241fc478′}
str = “-”
env2job_dict={‘qa-routine’:”checkout_rls”,’qa-emergy’:”checkout_full”,’prd’:”checkout_zxq_rls2rls”}
help=”’For example:
#不切分支
./jenkins_deploy.py rebuild qa-job1,qa-job2,qa-job3
#qa例行发布
./jenkins_deploy.py qa-routine qa-job1,qa-job2,qa-job3,qa-job4
#qa紧急发布
./jenkins_deploy.py qa-emergy qa-job1,qa-job2,qa-job3
#生产、预生产发布
./jenkins_deploy.py prd prd-job1,prd-job2,prd-job3,prd-job4”’

class myjenkins:
def __init__(self,env):
self.server = jenkins.Jenkins(url_dict[env],
username=username_dict[env],
password=token_dict[env])

def build_job(self,job_name,param_dict=”):
next_build_num=self.server.get_job_info(job_name)[‘nextBuildNumber’]
if param_dict==”:
self.server.build_job(job_name)
else:
self.server.build_job(job_name,parameters=param_dict)
while 1:
try:
result=self.server.get_build_info(job_name,next_build_num)
if (result[‘result’] != None) and (result[‘building’] == False):
break
except:
continue
print(“%s(%s) build %s” %(job_name,result[‘displayName’],result[‘result’]))
return result[‘result’]

@staticmethod
def usage():
print(help)

def func(job_name,branch_do):
job_name=job_name.strip()
env = job_name.split(‘-‘)[0]
project_name = job_name.split(‘-‘)[1:]
project_name = str.join(project_name)
#newrvm特殊
project_name = project_name.strip(‘-BJ’)
project_name = project_name.strip(‘-SH’)
project_name = project_name.strip(‘-GB’)
project_name = project_name.strip(‘-SH-Auding’)
project_name = project_name.strip(‘-SH-Old’)

a = myjenkins(env)
if branch_do != ‘rebuild’:
checkout_result = a.build_job(env2job_dict[branch_do], {‘ProjectName’: project_name})
else:
checkout_result = ‘SUCCESS’

if checkout_result == ‘SUCCESS’:
a.build_job(job_name)
else:
print(“Checkout % failed” % (job_name))

def main():
branch_do=sys.argv[1]

if branch_do == ‘–help’:
myjenkins.usage()
exit()

jobs = sys.argv[2]
jobs=jobs.split(‘,’)

if jobs != []:
for job_name in jobs:
S=threading.Thread(target=func,args=(job_name,branch_do))
S.start()
time.sleep(15) #不sleep的话,切分支会抓到同一个next_build_num

if __name__ == ‘__main__’:
main()

mongos进程检测脚本-shell

#!/bin/bash

while true
do
pid=`cat /app/data/mongodb/pid`
PID=`ps -ef | grep mongo | grep config | awk ‘{print $2}’`
if [ $PID -eq $pid ];then
date
echo “mongos is running”
sleep 300
else
echo “mongos restarted”
mongos –config /app/svr/mongodb/mongos.yaml
sleep 300
fi
done

知识点1:while循环的话,一定要在每个命令下面加上sleep延时,以免程序出错。
知识点2:date指打印出时间
知识点3:启动脚本不建议用crontab,一般用nohup ./*.sh &

grep知识点

ansible中hosts的文件如下:
[prd-sp-xx]
x.x.x.x
x.x.x.x
[pp-sp-xx]
x.x.x.x
x.x.x.x
[qa-sp-xx]
x.x.x.x
x.x.x.x
[dev-sp-xx]
x.x.x.x
x.x.x.x

对于该格式的内容,如何过滤出想要的内容
cat /etc/ansible/hosts | grep -A 2 prd- | grep -v -E “\[|–”
知识点1:grep -A 2 prd-
就是过滤出包含prd标题及下面2行
知识点2:grep -E “file1|file2”
就是多个file利用管道连接执行
备注:grep -E就是’egrep’

自动推送微信公共账号群消息

微信公众平台的基础接口没有推送群消息的api(高级接口貌似也没有),所以用python写了个程序模拟微信公众平台的post请求来实现这个功能,附带实现了发送消息给单个用户。

需要的模块

requests:给人用的HTTP请求模块,python自带的urllib和urllib2实在是难用。requests支持会话模式,意思就是所有的请求都用一个实例,共享同一个cookies,十分方便。具体参考官方文档(中文):http://cn.python-requests.org/zh_CN/latest/index.html

实现

requests.seesion()就是会话模式

首先设置主请求头

然后login()函数登录,获取token。发送的密码用md5加密

最后masssend()函数发送群消息

singlesend()函数用来给单人发送消息,形参tofakeid不是用户的微信号,并且和api中”FromUserName 发送方帐号”也不一样,这样就没办法将用户直接关联起来,只能手动观察绑定-。-

ps:如果在本机浏览器上登录了微信公众平台,然后在另一个电脑上运行脚本,可能会导致脚本登录失败,解决的办法是退出本机登录。

自动化日常巡检程序-Python实现

程序说明

程序是通过使用python实现ssh连接到服务器去实行shell脚本,返回数据,并且生成excel,对不正常指标进行标红处理。

Python要实现ssh连接服务器还需要其他模块。

python-2.7.5、paramiko-1.15.2、xlwt-1.0.0

程序流程

daily check

由于这边是在windows下面执行的,下面我将改成在linux系统下面执行

程序结构与程序说明

此程序由主程序、主机信息文件、命令文件三个文件组成。

` daily_check.py <此文件是python的主程序
` 日期ycq.txt <生成的巡检信息文件
` check.log <日志文件
| hosts <存放着要执行那些命令和检查那些主机的文件
|     ` host.info <存放着需要巡检的主机IP和用户名密码
|     `xx.xx.xx.xx.sh<–脚本文件生成下面的文件
|     ` xx.xx.xx.xx.cmd <存放相关主机需要执行的命令
执行了daily_check.py生成了xunjian.txt文件,我们需要将文件的内容都拷贝到一个excel文件中查看。

并标出相关的预警的信息。如下:

daily check上图显示了5列:

  • 项目:检查了什么。
  • 命令:检查使用的命令。
  • 基线:比对的标准。
  • 巡检情况:检查出来的信息。
  • 主机:是在那台主机上检查的。
    • *.cmd文件

    此文件存放了巡检需要执行的命令、校验标准和命令是检查什么项目的,如下图:

    daily check
  • 以上文件的每一行分为3个部分:
    • 校验项目。
    • 校验shell命令。
    • 校验标准:校验标准指定一个操作符号(>、<、=),具体用途例如:<85% 如果检查出来的结果 >85%就超标了。

    以上三个部分是使用 “#” 分割(注意:请在命令中避免使用 “#”,以免出现程序分割错误)。

    host.info文件

    此文件中存放了需要巡检的主机的IP和用户名信息,它们使用空格分开,如果有不需要巡检的主机可以在里面使用 (#) 在注释,和shell脚本的注释是一样的。如图:

    daily check

如果有行的服务器需要巡检,需要添加相关 主机 信息到此文件中。

执行巡检先要执行xx.xx.xx.xx.sh脚本,生产xx.xx.xx.xx.cmd,然后再执行主程序daliy_check.py,现将脚本贴到下面:
1.主程序:daliy_check.py
#!/bin/env python
# -*- coding:utf-8 -*-

# program: ssh remote execute command
#          genaral data story local
# author: ycq
# date: 2017-08-18

import sys
import paramiko
import xlwt
import time
from datetime import datetime
import logging

logging.basicConfig(level=logging.INFO,
format=’%(asctime)s %(name)-12s %(levelname)-8s %(message)s’,
filename=’check.log’,
filemode=’w’,
datefmt=’%Y-%m-%d %X’)
reload(sys)
ISOTIMEFORMAT=’%Y-%m-%d’
sys.setdefaultencoding(‘utf-8’)

def header(work_sheet):
work_sheet.write(0, 0, ‘检查项目’, style0)
work_sheet.write(0, 1, ‘命令’, style0)
work_sheet.write(0, 2, ‘基准’, style0)
work_sheet.write(0, 3, ‘检查结果’, style0)
work_sheet.write(0, 4, ‘检查主机’, style0)
logging.info(‘header add ok!’)
return work_sheet

def run_host_sh(host, port, username, password, work_sheet):
ssh = paramiko.SSHClient()
command_file = open(‘./hosts/’ + host + ‘.cmd’, ‘r’)

for line in command_file.readlines():
rows = len(work_sheet.rows)
line = line.strip(‘\n’)
items = line.split(‘:’)

check_type = items[0].decode(‘utf-8’).encode(‘utf-8’)
check_cmd = items[1].decode(‘gbk’).encode(‘utf-8’)
check_base_line = items[2].decode(‘gbk’).encode(‘utf-8’)
opration = check_base_line[0:1]
base_value = check_base_line[1:]

work_sheet.write(rows, 0, check_type)
work_sheet.write(rows, 1, check_cmd)
work_sheet.write(rows, 2, check_base_line)

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(host, port, username, password, key_filename=None, timeout=2)
except Exception, e:
logging.error(‘can not connect host: ‘ + host)
logging.error(‘command can not exec: ‘ + check_cmd)
logging.error(e)
continue
stdin, stdout, stderr = ssh.exec_command(check_cmd)
return_info = stdout.read().strip()

style_red = xlwt.easyxf(‘pattern: pattern solid, fore_colour red;’ +
‘font: name Times New Roman, color-index black, bold on;’ +
‘borders: left thick, right thick, top thick, bottom thick;’ +
‘align: horiz center’)

error_flag = False

if opration == ‘>’:
if str(base_value) > str(return_info):
error_flag = True
elif opration == ‘=’:
if str(return_info) != str(base_value):
error_flag = True
elif opration == ‘<‘:
if str(base_value) < str(return_info):
error_flag = True

if error_flag:
logging.warning(host + ‘ checked diff’)
logging.warning(‘command is: ‘ + check_cmd)
work_sheet.write(rows, 3, return_info.decode(‘gbk’).encode(‘utf-8’), style_red)
else:
work_sheet.write(rows, 3, return_info.decode(‘gbk’).encode(‘utf-8’))

work_sheet.write(rows, 4, ‘server IP: ‘ + host)

check_info = check_type + ‘\t’ + check_cmd + ‘\t’ + check_base_line + ‘\t’ + return_info
check_info = check_info.strip(‘\n’)
check_info += ‘\t’ + ‘server IP: ‘ + host
logging.info(check_info)
command_file.close()
ssh.close()
return work_sheet

if __name__==’__main__’:
#   try:
#     main()
#   except Exception,e:
#     print e

style0 = xlwt.easyxf(‘pattern: pattern solid, fore_colour yellow;’ +
‘font: name Times New Roman, color-index black, bold on;’ +
‘borders: left thick, right thick, top thick, bottom thick;’ +
‘align: horiz center’,
num_format_str=’0,000.00′)

work_book = xlwt.Workbook(encoding=’utf-8′)
work_sheet = work_book.add_sheet(‘A Test Sheet’)
work_sheet = header(work_sheet)

hosts_file = open(‘./hosts/host.info’, ‘r’)

for line in hosts_file.readlines():
if line[0:1] == ‘#’: continue
line = line.strip(‘\n’)
items = line.split()
port = 22
host = items[0]
username = items[1]
password = items[2]

work_sheet = run_host_sh(host, port, username, password, work_sheet)
logging.info(host + ‘ check finish !\n’)
file_pre = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
work_book.save(file_pre + ‘_ycq.xls’)

2.host.info
xx.xx.xx.xx user passwd
3.xx.xx.xx.xx.sh
#!/bin/bash
disk=$(df -lP | grep -e ‘/alidata1$’ | awk ‘{print $5}’)
echo -e 磁盘空间:$disk:”<85%” > 10.14.12.20.cmd
used_free=$(free -m | sed -n ‘2p’ | awk ‘{printf(“%d%\n”,$3/$2*100)}’)
echo -e 已使用内存:$used_free:”<10%” >> 10.14.12.20.cmd

检查IP是否存活

#!/bin/bash
IP=10.14.12
NODE=1
while [ “$NODE” -lt “255” ];
do
echo -en “Pinging ${IP}.${NODE}…”
ping -c1 -w1 -t5 ${IP}.${NODE} >/dev/null 2>&1
if [ “$?” -eq “0” ];then
echo “ok”
else
echo “failed”
fi
let NODE=$NODE+1
done

nginx日志按天截取

编写cut_nginx_log.sh脚本,脚本如下:

#!/bin/bash
logs_path=/app/lb/tengine-2.1.1/logs
yesterday=$(date -d “yesterday” +%Y-%m-%d)
mv ${logs_path}/access.log ${logs_path}/access_${yesterday}.log
mv ${logs_path}/error.log ${logs_path}/error_${yesterday}.log
kill -USR1 $(cat $logs_path/nginx.pid)

 

写好脚本之后,增加crontab定时任务,每天的00:00做日志切割

0 0 * * * /bin/bash /app/lb/tengine-2.1.1/cut_nginx_log.sh

curl与wget高级用法

curl(文件传输工具)

常用参数如下:

使用示例:
例1:抓取页面到指定文件,如果有乱码可以使用iconv转码

例2:模拟浏览器头(user-agent)

例3:处理重定向页面

例4:模拟用户登陆,保存cookie信息到cookies.txt文件,再使用cookie登陆

例5:获取HTTP响应头headers

例6:访问HTTP认证页面

例7:通过ftp上传和下载文件

wget(文件下载工具)

常用参数如下:

使用示例:
例1:下载单个文件到当前目录下,也可以-P指定下载目录

例2:对于网络不稳定的用户可以使用-c和–tries参数,保证下载完成

例3:下载大的文件时,我们可以放到后台去下载,这时会生成wget-log文件来保存下载进度

例4:可以利用—spider参数判断网址是否有效

例5:自动从多个链接下载文件

例6:限制下载速度

例7:登陆ftp下载文件