我們經常會遇到監控一個文件或目錄的變化,如果有變化,把文件上傳備份至備份主機,並且我們還要監控上傳過程是否有問題等,根據此需求,查閱了相關的一些材料,編寫如下腳本實現這個功能:


    #!/usr/bin/env python #coding=utf-8 ####################### # #status wd gss sql file changed #date:2013-08-26  王偉 #文件有變化上傳至備份主機,上傳之後驗證文件是否正確 # #######################import paramiko,os,sys,datetime,time,mysqldbfrom pyinotify import watchmanager, notifier, processevent, in_delete, in_create,in_modify\''\''\''create table `wddel_log.status_sql` (  `ip` varchar(16) not nullment \''機器ip\'',  `tar_name` varchar(50) not nullment \''備份文件名字\'',  `md5` varchar(50) not nullment \''備份文件 md5\'',  `g` int(2) not nullment \''0:成功;1:失敗\'',  `error_log` varchar(100) not nullment \''錯誤日誌\'',  `uptime` datetime not nullment \''更新時間\'',  key `ip` (`ip`),  key `uptime` (`uptime`)) engine=innodb default charset=utf8\''\''\''#日誌表創建腳本gm_path=\''/home/asktao/\''center_hostname=\''192.168.1.100\''center_username=\''root\''center_password=\''123456\''center_port=63008def log2db(ip,tar_name,md5,g,error=\''0\''):#刪除日誌入庫    try:tar_name = os.path.split(tar_name)[1]now  = time.strftime("%y-%m-%d %h:%m:%s")conn = mysqldb.connect(host = \''192.168.1.104\'',user = \''root\'',passwd = \''1q2w3e4r\'',charset=\''utf8\'',connect_timeout=20)cursor = conn.cursorsql = "select ip from wddel_log.status_sql where ip=\''%s\''" % ipcursor.execute(sql)res = cursor.fetchallif len(res)==0:    inster_sql = "insert into wddel_log.status_sql values(\''%s\'',\''%s\'',\''%s\'',%s,\''%s\'',\''%s\'')" % (ip,tar_name,md5,g,error,now)    cursor.execute(inster_sql)    connmitelse:    update_sql = "update wddel_log.status_sql set md5=\''%s\'',g=\''%s\'',error_log=\''%s\'',uptime=\''%s\'' where ip=\''%s\''" % (md5,g,error,now,ip)    cursor.execute(update_sql)    connmitcursor.closeconn.close    except exception,e:print edef find_ip:#獲取本地 eth0 的 ip 地址    ip = os.popen("/sbin/ip a|grep \''global eth0\''").readlines[0].split[1].split("/")[0]    if "192.168." in ip:ip = os.popen("/sbin/ip a|grep \''global eth1\''").readlines[0].split[1].split("/")[0]    return ipdef md5sum(file_name):#驗證 sql 打包文件的 md5    if os.path.isfile(file_name):f = open(file_name,\''rb\'')py_ver = sys.version[:3]if py_ver == "2.4":    import md5 as hashlibelse:    import hashlib    md5 = hashlib.md5(f.read).hexdigest    f.close    return md5    else:return 0def center_md5(file_name):#上傳至備份中心的文件的 md5    try:s=paramiko.sshclients.set_missing_host_key_policy(paramiko.autoaddpolicy)s.connect(hostname = center_hostname,port=center_port,username=center_username, password=center_password)conm = "/usr/bin/md5sum %s" % file_namestdin,stdout,stderr=s.execmand(conm)result = stdout.readlines[0].split[0].strips.closereturn result    except exception,e:return edef back_file(ip,tar_name,tar_md5):#上傳文件到備份中心    remote_dir=\''/data/sql\''    file_name=os.path.join(remote_dir,os.path.split(tar_name)[1])    try:t=paramiko.transport((center_hostname,center_port))t.connect(username=center_username,password=center_password)sftp=paramiko.sftpclient.from_transport(t)sftp.put(tar_name,file_name)t.close#print "%s back_file ok" % tar_nameos.remove(tar_name)remot_md5=center_md5(file_name)if remot_md5 == tar_md5:    log2db(ip,tar_name,tar_md5,0)else:    log2db(ip,tar_name,tar_md5,1,\''remot_md5!=tar_md5\'')    except exception,e:#print "connect error!"log2db(ip,tar_name,tar_md5,1,e)os.remove(tar_name)def back_sql:#執行備份    ip = find_ip    tar_name = "/tmp/%s.tar.gz" % ip    sql_conn = "/usr/bin/find %s -type f  -name \''*.sql\''|/usr/bin/xargs /bin/tar zcvpf %s" % (gm_path,tar_name)    sql_tar = os.popen(sql_conn).readlines    tar_md5 = md5sum(tar_name)    if tar_md5 != 0:back_file(ip,tar_name,tar_md5)    else:error_log =  "%s not find" % tar_namelog2db(ip,tar_name,tar_md5,0,error_log)ss pfilepath(processevent):#文件變化的觸發    def process_in_create(self, event):if os.path.splitext(event.name)[1] == ".sql":    text = "create file: %s " % os.path.join(event.path, event.name)    #print text    back_sql    def process_in_modify(self, event):if os.path.splitext(event.name)[1] == ".sql":    text = "modify file: %s " % os.path.join(event.path, event.name)    #print text    back_sqldef fsmonitor:#主監控函數    back_sql#運行腳本先備份 sql 文件    wm = watchmanager    mask = in_create |in_modify    notifier = notifier(wm, pfilepath)    wdd = wm.add_watch(gm_path, mask, rec=true)    print \''now starting monitor %s\'' % (gm_path)    while true:try :    notifier.process_events    if notifier.check_events:notifier.read_eventsexcept keyboardinterrupt:    notifier.stop    breakif __name__ == "__main__":    fsmonitor  </pre>


    此腳本中主要用到 paramiko 和 pyinotify 模塊,關於 paramiko 的講解可以參見:http://wangwei007.blog.51cto/68019/1058726一文,pyinotify 的用法可以參見官方文檔:https://github/seb-m/pyinotify/wiki/events-types

章節目錄

閱讀記錄

Python實戰-從菜鳥到大牛的進階之路所有內容均來自互聯網,鉛筆小說網隻為原作者極客學院的小說進行宣傳。歡迎各位書友支持極客學院並收藏Python實戰-從菜鳥到大牛的進階之路最新章節