项目需要获取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的备份进度了
本文标题:用python实时获取shell命令的输出[rsync备份进度]
本文链接:http://www.maben.com.cn/archives/623.html转载请注明出处