項目需要獲取rsync備份的實時進度,主要是用到subprocess模塊的管道功能,網上查了查是有人這麼寫的: popen = subprocess.Popen(['ping', 'www.baidu.com', '-n', '3'], stdout = subprocess.PIPE)while True: print popen.stdout.readline() 用到subproces
項目需要獲取rsync備份的實時進度,主要是用到subprocess模塊的管道功能,網上查了查是有人這麼寫的:
popen = subprocess.Popen(['ping', 'www.baidu.com', '-n', '3'], stdout = subprocess.PIPE) while True: print popen.stdout.readline()
用到subprocess.Popen方法,把stdout參數定位到subprocess.PIPE裏面,這一招對於像’ping’這樣的命令是可以的,因爲ping是一行一行打印的,可以直接用readline來獲取,但是像rsync這種軟件的進度是在一行裏面實時刷新的,顯示進度的緩衝區並沒有釋放,所以用readline就讀不出來,還是得等到整個程序執行結束之後才能返回。查了查手冊和資料,發現stdout可以定義到文件對象,試了一下,可以解決:
import subprocess import sys import time import random import os import re if __name__ == '__main__': cmdLine = [] cmdLine.append('rsync')
cmdLine.append('--progress') cmdLine.append('/kvmdata/kvm/VM_winxp/winxp.img') cmdLine.append('/root/winxp.img') tmpFile = "./tmp/%d.tmp" % random.randint(10000,99999) #臨時生成一個文件 fpWrite = open(tmpFile,'w') process = subprocess.Popen(cmdLine,stdout = fpWrite,stderr = subprocess.PIPE); while True: fpRead = open(tmpFile,'r') #這裏又重新創建了一個文件讀取對象,不知爲何,用上面的就是讀不出來,改w+也不行 lines = fpRead.readlines() for line in lines: print line if process.poll(): break; fpWrite.truncate() #此處清空文件,等待記錄下一次輸出的進度 fpRead.close() time.sleep(3) fpWrite.close() error = process.stderr.read() if not error == None: print 'error info:%s' % error os.popen('rm -rf %s' % tmpFile) #刪除臨時文件 print 'finished'
這樣就可以實時獲取到Rsync的備份進度了