python 探索(四) Python CookBook 系统管理

看CookBook就像看小说,挑感兴趣的先学习。

所以继《文本》之后,开始《系统管理》。

同样,请善用目录。

发现一个cookbook:好地址


生成随机密码

from random import choice
import string

def GenPasswd(length = 8,chars = string.letters+string.digits):
    return ''.join([choice(chars) for i in range(length)])

for i in range(6):
    print GenPasswd(12)

结果:
>>> 
fnkdz5dPA3zu
TZF9HzndkrSb
fiGAfBU8y2rk
QRmtzTzNnxFR
RJp8Cv6CsEHV
9kPHiFUJ7uWz
>>> 


拓展阅读:

Python中的random模块 - Capricorn.python - 博客园(random的常见操作,很清晰)



生成易记的伪随机密码

 

import random,string

class password(object):
    def __init__(self,filename):
        self.data = open(filename).read().lower()
    def renew(self,n = 8,maxmem = 3):
        chars = []
        for i in range(n):
            rmdIndex = random.randrange(len(self.data)) 
            self.data = self.data[rmdIndex:]+self.data[:rmdIndex]
            where = -1
            locate = chars[-maxmem:]
            while where < 0 and locate:
                where = self.data.find(str(locate))
                locate = locate[1:]
            ch = self.data[where+len(locate)+1]
            if not ch.islower():
                ch = random.choice(string.lowercase)
            chars.append(ch)
        return ''.join(chars)

p = password("c:\\LICENSE.txt")
print p.renew(12)

 


思想:

(1)对于每一个随机字符,我们都按照以下流程处理一遍

(2)随机找到中间点,然后分成两段,翻转合并

(3)用最后的结果的倒数maxmem个字符来做locate标记

(4)每次找到这个locate处,若找不到,locate缩减为locate[1:],继续找,直到找到为止

(5)我们要的本次的随机字符就是找到的locate处的后一个字符self.data[where+len(locate)+1],如果locate为空,那么ch就是(2)后的第一个字符,也是随机的


拓展阅读:

马尔科夫链wiki




以POP服务器的方式验证用户

其实这种用代码来验证POP3,用处何在呢?明文还不安全。

 

import poplib

def checkPOP3User(host,user,password):
    try:
        pop = poplib.POP3(host)
    except:
        raise RuntimeError("Could not establish connection"
                           "to %r for password check" % host)
    try:
        pop.user(user)
        pop.pass_(password)
        count,size = pop.stat()
        assert type(count) == type(size) == int
        print count,size
        pop.quit()
    except:
        raise RuntimeError("Could not verify identity. \n"
                        "User name %r or password incorrect." % user)
        pop.quit()

checkPOP3User("pop.qq.com","411187674@qq.com","123456")


Ps:看了RuntimeError之后才发现,字符串可以s = "123""abc"这么写

 


思想:

(1)POP3.user(username)
Send user command, response should indicate that a password is required.

(2)POP3.pass_(password),请注意我不是pass,而是pass_
Send password, response includes message count and mailbox size. Note: the mailbox on the server is locked until quit() is called.

(3)POP3.stat()
Get mailbox status. The result is a tuple of 2 integers: (message count, mailbox size).

(4)记得用raise ,对了那个密码是我乱写的,别猜了,但是qq是对的

拓展阅读:

poplib的API

python中的异常处理-kouyanghao-ChinaUnix博客(异常的各种用法)



统计Apache中每个IP的点击率

import re

def calcuteApacheIpHits(logfile_pathname):
    ip_specs = r'\.'.join([r'\d{1,3}']*4)
    re_ip = re.compile(ip_specs)

    ipHitListing = {}
    contents = open(logfile_pathname,"r")
    for line in contents:
        match = re_ip.match(line)
        if match :
            ip = match.group()
            #检查正确性
            try:
                quad = map(int,ip.split('.'))
            except ValueError:
                pass
            else:
                #如果ip存在就+1,不存在就设置为1
                if len(quad) == 4 and min(quad) >= 0 and max(quad) <= 255: 
                    ipHitListing[ip] = ipHitListing.get(ip,0) + 1
    return ipHitListing

print calcuteApacheIpHits("log.txt")

思想:
(1)按行读内容,正则匹配
(2)检查IP范围,min 和 max 的妙用
(3)存在+1,不存在置1:list[ip] = list.get(ip,0) + 1,这里的get中的0是指获取不到ip的时候的默认值


统计Apache的客户缓存的命中率

Ps:我觉得这道题要是去笔试,要考倒一大波人。

def clientCachePercentage(logfile_pathname):
    contents = open(logfile_pathname,"r")
    totalRequests = 0
    cachedRequests = 0
    for line in contents:
        totalRequests += 1
        if line.split(" ")[8] == "304":
            cachedRequests += 1
    return int(0.5+float(100 * cachedRequests)/totalRequests)

print clientCachePercentage("1.txt")

思想:
(1)浏览器请求·一个在它的缓存中的服务器页面的时候,浏览器会首先让服务器了解浏览器的缓存数据,若客户缓存更新过,那么返回一个304错误
(2)统计log文件中的304有多少,然后和全部请求一对比,就出来缓存命中率了


在脚本中调用编辑器


这个就是 普通的调用下编辑器来编辑内容。

Ps:建议在 Linux下使用本脚本。win下,找不到os.spawnlp这个方法。
import sys,os,tempfile

def what_editor():
	editor = os.getenv('VISUAL') or os.getenv('EDITOR')
	if not editor:
		if sys.platform == 'windows':
			editor = 'Notepad.Exe'
		else:
			editor = 'vi'
	return editor

def edited_text(starting_text = ''):
	temp_fd,temp_filename = tempfile.mkstemp(text = True)
	os.write(temp_fd,starting_text)
	os.close(temp_fd)
	editor = what_editor()
	x = os.spawnlp(os.P_WAIT,editor,editor,temp_filename)
	if x:
		raise RuntimeError, "Can't run %s %s (%s)" % (editor,temp_filename,x)
	result = open(temp_filename).read()
	os.unlink(temp_filename)
	return result

if __name__ == '__main__':
	text = edited_text('''aaaaaaaa
bbbbbbb
cccccccc''')
	print 'Edited text is:',text



思想:
(1)os.spawnlp(os.P_WAIT,editor,editor,temp_filename)
参数一:os.P_WAIT是父进程等待子进程返回
参数二:editor是子进程对应的file,比如“/dev/cp”中的cp就是一个file
参数三:剩下的都是参数args:editor filename -> vi  temp.txt 
(2)os.getenv(varname),得到环境变量的varname的值吗,如果没有则None
(3)os.remove(path) 和 os.unlink(path) 一样,删除文件
(4)tempfile.mkstemp,返回句柄+pathname,如果text=True,与二进制文件,文本文件有关系

拓展阅读:


备份文件

这个小节,绝对最重要的,就是这个备份了。
import sys,os,shutil,filecmp

MAXVERSIONS = 100
def backup(tree_top,bakdir_name = 'bakdir'):
    for root,subdirs,files in os.walk(tree_top):
        #join链接出每个root下的子目录bakdir
        backup_dir = os.path.join(root,bakdir_name)
        #确保每个root下都有个子目录叫bakdir
        if not os.path.exists(backup_dir):
            os.makedirs(backup_dir)
        #bakdir下的不递归处理
        subdirs[:] = [d for d in subdirs if d != bakdir_name]

        for file in files:
            filepath = os.path.join(root,file)
            destpath = os.path.join(backup_dir,file)
            #检查版本,共有MAXVERSIONS个版本
            for index in xrange(MAXVERSIONS):
                backup = "%s.%2.2d" % (destpath,index)
                if not os.path.exists(backup):
                    break
            if index > 0:
                old_backup = "%s.%2.2d" % (destpath,index-1)
                #abspath = os.path.abspath(filepath)#filepath本来就是绝对路径
                try:
                    #如果备份和源文件一致,continue不处理
                    if os.path.isfile(old_backup) and filecmp.cmp(filepath,old_backup,shallow = False):
                        continue
                except OSError:
                        pass
            try:
                shutil.copy(filepath,backup)
            except OSError:
                pass

if __name__ == '__main__':
    backup("c:\\test")
    

结果:

进到备份文件夹中:


拓展阅读:



【Pass三连发,邮箱国内外行情不一样,以后若有必要,再补上】

选择性地复制邮箱文件

pass

通过邮箱创建一个邮件地址的白名单

pass

阻塞重复邮件

pass


检查你的Windows声音系统

import winsound

try:
    winsound.PlaySound("*",winsound.SND_ALIAS)
except RuntimeError,e:
    print 'Sound system has problems,',e
else:
    print 'Sound system is OK'

思想:
(1)竟然还有个专门处理win下的sound的 winsound,python你这个要逆天吗
(2)winsound.SND_ALIAS 播放默认声音,具体看拓展阅读

拓展阅读:


在Windows中注册和反注册DLL

from ctypes import windll

dll = windll[r'C:\\WINDOWS\\system32\\alrsvc.dll']

result = dll.DllRegisterServer()
result = dll.DllUnregisterServer()
然后的result是Windows类型的HRESULT。

以下版本还带检查,错误会抛出个ctypes.WindowsError
from ctypes import oledll

dll = oledll[r'C:\\WINDOWS\\system32\\alrsvc.dll']

result = dll.DllRegisterServer()
result = dll.DllUnregisterServer()


思想:
(1)windll.ctypes 关于dll,知道有这么一个货
(2)用法很简单,一个注册,一个反注册
(3)和 regsvr32.exe有关

Ps:暂时没用到。先记录下来。


检查并修改Windows自动运行任务

# -*- coding: cp936 -*-

import  _winreg  as wr

def how_many_tasks_at_logon():
    areg = wr.ConnectRegistry(None,wr.HKEY_LOCAL_MACHINE)
    akey = wr.OpenKey(areg,r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run')
    try:
        for i in xrange(1024):
            try:
                name,value,int_type = wr.EnumValue(akey,i)
                print i,name,value,int_type
            except EnvironmentError:
                print "You have",i,"tasks strating at logon"
                break
    finally:
        wr.CloseKey(akey)

def wirte_to_registry(root_key,arg,value_name,value):
    areg = wr.ConnectRegistry(None,root_key)
    akey = wr.OpenKey(areg,arg,0,wr.KEY_WRITE)
    try:
        try:
            wr.SetValueEx(akey,value_name,0,wr.REG_SZ,value)
        except EnvironmentError:
            print "Encountered problems writing into the Registry"
            raise
    finally:
        wr.CloseKey(akey)
def delete_from_registry(root_key,arg,value_name):
    areg = wr.ConnectRegistry(None,root_key)
    akey = wr.OpenKey(areg,arg,0,wr.KEY_WRITE)
    try:
        try:
            wr.DeleteValue(akey,value_name)
        except EnvironmentError:
            print "Encountered problems deleting key from Registry"
            raise
    finally:
        wr.CloseKey(akey)

root_key = wr.HKEY_LOCAL_MACHINE
arg = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
value_name = "myOwnKey"
value = r"C:\Program Files\多玩英雄联盟盒子\LOLBox.exe"


print "=================reading=============== "
how_many_tasks_at_logon()
print "=================writing=============== "
wirte_to_registry(root_key,arg,value_name,value)

print "=================reading=============== "
how_many_tasks_at_logon()

print "=================deleting============== "
delete_from_registry(root_key,arg,value_name)

print "=================reading=============== "
how_many_tasks_at_logon()

结果:


思想:
(1)_winreg.ConnectRegistry(Computer_Name,key) 链接某电脑的key,本机为None,返回一个Handle Object
(2)_winreg.OpenKey(key,subkey,res = 0,sam = _winreg.KEY_READ) 打开一个指定key,res必须为0,sam是模式,这里默认为只读
(3)_winreg.EnumValue(key,index),返回key对应的第index个元组,元组:name,value,type(int,查表吧)
(4)_winreg.SetValueEx(key,value_name,reserved,type,value),reserved一般为0,type能有很多种如REG_SZ,REG_DWORD
(5)_winreg.DeleteValue(key,value_name) 
(6)_winreg.CloseKey(key)

Ps:一开始编程把EnumValue写成EnumKey,一直报错,囧。还有把DeleteValue写成DeleteKey,囧。
Ps:文盲的我亲测重启了下电脑,LOL盒子果然打开了。。差点就撸了一把。。一大早的,不能撸啊。。

这节也算多认识了一个raise : EnvironmentError,其实我感觉 WindowsError挺好的


在Windows中创建共享

import win32net
import win32netcon
import os

print('>>>正在运行共享文件夹设置程序...')

shinfo = {}
folder = "c:\\test"
shinfo['netname'] = os.path.basename(folder)
shinfo['type'] = win32netcon.STYPE_DISKTREE
shinfo['remark'] = 'data files'
shinfo['premissions'] = 0
shinfo['max_uses'] = -1
shinfo['current_uses'] = 0
shinfo['path'] = 'c:\\test'
shinfo['passwd'] = ''
server = r'\\.'
win32net.NetShareAdd(server,2,shinfo)

结果:
、、、


思想:
(1)特别感谢John Nielsen,没有你花了大量精力去收集拼凑,也没这代码的产生
(2)如果共享的文件夹已经被共享过,会raise Error


链接一个正在运行的Internet Explorer实例

from win32com.client import Dispatch
from win32gui import GetClassName

ShellWindowsCLSID = '{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
ShellWindows = Dispatch(ShellWindowsCLSID)

for shellwindow in ShellWindows:
    #筛选,Windows Explorer和Internet Explorer 是一样的,一个本地,一个网络
    #这里要IE
    if GetClassName(shellwindow.HWND) == 'IEFrame':
        print shellwindow,shellwindow.LocationName,shellwindow.LocationURL

结果:


思想:
(1)Windows Explorer 和 Internet Explorer ,竟然拥有相同的CLSID。。windows系统为每一个应用,组件,文件等分配一个身份ID
(2)借助 win32com.clientwin32gui,用python操作IE,很酷的说
(3)听说,这方法不可靠,对于各个版本,补丁的windows和IE不能确定。。


【不用outlook】

读取Microsoft Outlook Contacts

pass


【没有mac】

在Mac OS X 中收集详细的系统信息

pass

 

posted on 2013-10-09 19:18  you Richer  阅读(465)  评论(0编辑  收藏  举报